Menu
CoddyTech

is_a? và tổ tiên

Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 25 trên 57.

is_a?(Class) kiểm tra xem một đối tượng có phải là một thể hiện của lớp đó hoặc của bất kỳ lớp con nào của lớp đó hay không. kind_of? là một tên gọi khác của cùng phương thức này:

class Animal
end

class Dog < Animal
end

rex = Dog.new
puts rex.is_a?(Dog)
puts rex.is_a?(Animal)
puts rex.is_a?(Object)
puts rex.kind_of?(String)

Đầu ra:

true
true
true
false

instance_of? nghiêm ngặt hơn: nó chỉ là true khi lớp của chính đối tượng khớp. obj.class trả về lớp đó:

class Animal
end

class Dog < Animal
end

rex = Dog.new
puts rex.instance_of?(Dog)
puts rex.instance_of?(Animal)
puts rex.class

Đầu ra:

true
false
Dog

ancestors liệt kê các lớp mà Ruby tìm kiếm phương thức, bắt đầu từ chính lớp đó; danh sách đầy đủ cũng chứa các module như Kernel, sẽ được đề cập trong chương 6, vì vậy take(3) hiển thị ba mục đầu tiên. Bạn có thể so sánh các lớp: Dog < Animal là true khi Dog kế thừa từ Animal:

class Animal
end

class Dog < Animal
end

p Dog.ancestors.take(3)
puts Dog < Animal
puts Animal < Dog

Đầu ra:

[Dog, Animal, Object]
true
false

Dùng is_a? khi code cần xử lý một nhóm lớp theo cùng một cách, chẳng hạn như đếm tất cả động vật có vú, bất kể chúng thuộc lớp con nào. Việc kiểm tra một lớp cụ thể bằng instance_of? sẽ không còn phù hợp khi có người thêm lớp con:

mammals = animals.count { |a| a.is_a?(Mammal) }       # chó, dơi, cá voi...
exact = animals.count { |a| a.instance_of?(Mammal) }  # bỏ sót mọi lớp con
challenge icon

Thử thách

Dễ

Khai báo các lớp động vật: Animal, Mammal < Animal, Bird < Animal, Dog < Mammal, Bat < Mammal và Penguin < Bird. Animal lưu tên. Sau đó hoàn thành hàm trợ giúp describe(animal) trong functions.rb: hàm này trả về Rex is a dog: mammal, Pingu is a penguin: bird, với tên lớp viết thường và nhóm được xác định bằng is_a?.

Code được cung cấp đọc các dòng dog Rex, tạo các đối tượng, in kết quả của describe cho từng đối tượng, rồi mammals: 2, birds: 1.

Code của bạn nằm trong animal.rb, mammal.rb, bird.rb, dog.rb, bat.rb, penguin.rb và functions.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

require_relative 'animal'
require_relative 'mammal'
require_relative 'bird'
require_relative 'dog'
require_relative 'bat'
require_relative 'penguin'
require_relative 'functions'

# Đoạn code đầu vào/đầu ra đã có sẵn: giữ nguyên
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "dog" => "Dog", "bat" => "Bat", "penguin" => "Penguin" }
animals = input.map do |line|
  kind, name = line.split
  Object.const_get(kinds[kind]).new(name)
end
animals.each { |a| puts describe(a) }
mammals = animals.count { |a| a.is_a?(Mammal) }
birds = animals.count { |a| a.is_a?(Bird) }
puts "mammals: #{mammals}, birds: #{birds}"
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Ruby online