is_a? и предки
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 25 из 57.
is_a?(Class) проверяет, является ли объект экземпляром этого класса или любого его подкласса. kind_of? — другое название того же метода:
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)Вывод:
true
true
true
falseinstance_of? строже: оно равно true только для собственного класса объекта. obj.class возвращает этот класс:
class Animal
end
class Dog < Animal
end
rex = Dog.new
puts rex.instance_of?(Dog)
puts rex.instance_of?(Animal)
puts rex.classВывод:
true
false
Dogancestors перечисляет классы, в которых Ruby ищет методы, начиная с самого класса; полный список также содержит такие модули, как Kernel, которые рассматриваются в главе 6, поэтому take(3) показывает первые элементы. Классы можно сравнивать: Dog < Animal имеет значение true, когда Dog наследуется от Animal:
class Animal
end
class Dog < Animal
end
p Dog.ancestors.take(3)
puts Dog < Animal
puts Animal < DogВывод:
[Dog, Animal, Object]
true
falseИспользуйте is_a?, когда код должен одинаково обрабатывать группу классов, например подсчитывать всех млекопитающих независимо от того, к какому подклассу они относятся. Проверка одного точного класса с помощью instance_of? перестаёт работать, как только кто-то добавляет подкласс:
mammals = animals.count { |a| a.is_a?(Mammal) } # собаки, летучие мыши, киты...
exact = animals.count { |a| a.instance_of?(Mammal) } # пропускает каждый подклассЗадание
ЛегкоОбъявите классы животных: Animal, Mammal < Animal, Bird < Animal, Dog < Mammal, Bat < Mammal и Penguin < Bird. Animal хранит имя. Затем завершите вспомогательную функцию describe(animal) в functions.rb: она возвращает Rex is a dog: mammal, Pingu is a penguin: bird, используя имя класса в нижнем регистре, а группу определяя с помощью is_a?.
Предоставленный код считывает строки dog Rex, создаёт объекты, выводит describe для каждого из них, а затем mammals: 2, birds: 1.
Ваш код должен находиться в animal.rb, mammal.rb, bird.rb, dog.rb, bat.rb, penguin.rb и functions.rb. В main.rb находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
require_relative 'animal'
require_relative 'mammal'
require_relative 'bird'
require_relative 'dog'
require_relative 'bat'
require_relative 'penguin'
require_relative 'functions'
# Предоставленный код ввода/вывода: оставьте его как есть
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}"
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовПеременные экземпляраМетоды и selfto_s и inspectПовторение — читательский билет4Инкапсуляция
Приватные методыЗащищённые методыПриватные сеттерыЗащита состоянияПовторение — торговый автомат7Полиморфизм и утиная типизация
ПолиморфизмУтиная типизацияАбстрактные методыcase и классыПовторение — способы оплаты10Шаблоны проектирования, часть 2
Делегирование с помощью ForwardableШаблон декоратораШаблон строителяШаблон состояния2Аксессоры и self
Чтение и записьПользовательские сеттерыself в методахИдентичность и равенствоПовторение — список контактов5Наследование
ПодклассыПереопределение методовВызов superis_a? и предкиПовторение — расчёт зарплаты сотрудников8Специальные методы
Равенство и хешированиеМетоды операторовИндексация и добавлениеПользовательские коллекцииПовторение — дроби11Проект: Управление библиотекой
Книги и читателиВыдача книг3Методы и переменные классов
Методы классовПеременные экземпляра классаКонстантыФабричные методыПовторение — коды купонов6Модули и примеси
Модули и includeРасширение объектовМодуль ComparableМодуль EnumerableПовторение — спортивная лига9Паттерны проектирования. Часть 1
Паттерн «Одиночка»Фабричный паттернПаттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор Ruby