is_a? y ancestros
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 25 de 57.
is_a?(Class) pregunta si un objeto es una instancia de esa clase o de cualquiera de sus subclases. kind_of? es otro nombre para el mismo método:
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)Salida:
true
true
true
falseinstance_of? es más estricto: solo es true para la propia clase del objeto. obj.class devuelve esa clase:
class Animal
end
class Dog < Animal
end
rex = Dog.new
puts rex.instance_of?(Dog)
puts rex.instance_of?(Animal)
puts rex.classSalida:
true
false
Dogancestors enumera las clases en las que Ruby busca métodos, comenzando por la propia clase; la lista completa también contiene módulos como Kernel, que se aborda en el capítulo 6, por lo que take(3) muestra las primeras entradas. Las clases se pueden comparar: Dog < Animal es true cuando Dog hereda de Animal:
class Animal
end
class Dog < Animal
end
p Dog.ancestors.take(3)
puts Dog < Animal
puts Animal < DogSalida:
[Dog, Animal, Object]
true
falseUsa is_a? cuando el código deba tratar un grupo de clases de la misma manera, por ejemplo, para contar todos los mamíferos, independientemente de cuál sea su subclase. Preguntar por una única clase exacta con instance_of? deja de funcionar en cuanto alguien añade una subclase:
mammals = animals.count { |a| a.is_a?(Mammal) } # perros, murciélagos, ballenas...
exact = animals.count { |a| a.instance_of?(Mammal) } # omite todas las subclasesDesafío
FácilDeclara las clases de animales: Animal, Mammal < Animal, Bird < Animal, Dog < Mammal, Bat < Mammal y Penguin < Bird. Animal almacena un nombre. Después, completa la función auxiliar describe(animal) en functions.rb: devuelve Rex is a dog: mammal, Pingu is a penguin: bird, con el nombre de la clase en minúsculas y el grupo determinado mediante is_a?.
El código proporcionado lee líneas dog Rex, crea los objetos, imprime describe para cada uno y después mammals: 2, birds: 1.
Tu código va en animal.rb, mammal.rb, bird.rb, dog.rb, bat.rb, penguin.rb y functions.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'animal'
require_relative 'mammal'
require_relative 'bird'
require_relative 'dog'
require_relative 'bat'
require_relative 'penguin'
require_relative 'functions'
# Código de entrada/salida suministrado: déjalo tal como está
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}"
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Compilador de Ruby online