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
falseinstance_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
Dogancestors 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
falseDù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 conThử 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}"
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
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpBiến instancePhương thức và selfto_s và inspectÔn tập: thẻ thư viện4Tính đóng gói
Phương thức riêng tưPhương thức được bảo vệPhương thức thiết lập riêng tưBảo vệ trạng tháiÔn tập: máy bán hàng tự động7Tính đa hình và duck typing
Tính đa hìnhDuck typingPhương thức trừu tượngcase và lớpÔn tập: phương thức thanh toán2Phương thức truy cập và self
Phương thức đọc và ghiPhương thức gán tùy chỉnhself trong phương thứcĐịnh danh và tính bằng nhauÔn tập: Danh sách liên hệTự luyện tập: Trình biên dịch Ruby online