Menu
CoddyTech

is_a? und Vorfahren

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 25 von 57.

is_a?(Class) fragt, ob ein Objekt eine Instanz dieser Klasse oder einer ihrer Unterklassen ist. kind_of? ist ein anderer Name für dieselbe Methode:

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)

Ausgabe:

true
true
true
false

instance_of? ist strenger: Es ist nur dann true, wenn es sich um die eigene Klasse des Objekts handelt. obj.class gibt diese Klasse zurück:

class Animal
end

class Dog < Animal
end

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

Ausgabe:

true
false
Dog

ancestors listet die Klassen auf, in denen Ruby nach Methoden sucht, beginnend mit der Klasse selbst; die vollständige Liste enthält auch Module wie Kernel, das in Kapitel 6 behandelt wird, daher zeigt take(3) die ersten Einträge. Klassen lassen sich vergleichen: Dog < Animal ist true, wenn Dog von Animal erbt:

class Animal
end

class Dog < Animal
end

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

Ausgabe:

[Dog, Animal, Object]
true
false

Verwende is_a?, wenn der Code eine Gruppe von Klassen gleich behandeln muss, zum Beispiel, um alle Säugetiere zu zählen, unabhängig davon, welcher Unterklasse sie angehören. Die Abfrage nach einer ganz bestimmten Klasse mit instance_of? schlägt fehl, sobald jemand eine Unterklasse hinzufügt:

mammals = animals.count { |a| a.is_a?(Mammal) }       # Hunde, Fledermäuse, Wale...
exact = animals.count { |a| a.instance_of?(Mammal) }  # erfasst keine Unterklassen
challenge icon

Aufgabe

Einfach

Deklariere die Tierklassen: Animal, Mammal < Animal, Bird < Animal, Dog < Mammal, Bat < Mammal und Penguin < Bird. Animal speichert einen Namen. Vervollständige dann den Hilfsfunktion describe(animal) in functions.rb: Sie gibt Rex is a dog: mammal, Pingu is a penguin: bird zurück, wobei der Klassenname kleingeschrieben wird und die Gruppe mit is_a? bestimmt wird.

Der bereitgestellte Code liest Zeilen dog Rex, erstellt die Objekte, gibt für jedes describe aus und anschließend mammals: 2, birds: 1.

Dein Code gehört in animal.rb, mammal.rb, bird.rb, dog.rb, bat.rb, penguin.rb und functions.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

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

# Vorgegebener Eingabe-/Ausgabecode: unverändert lassen
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler