Вызов super
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 24 из 57.
Внутри переопределяющего метода super вызывает версию того же метода из суперкласса. Подкласс может использовать результат, вместо того чтобы повторять его:
class Greeter
def greet(name)
"Hello, #{name}"
end
end
class LoudGreeter < Greeter
def greet(name)
super.upcase + "!"
end
end
puts LoudGreeter.new.greet("Ada")Вывод:
HELLO, ADA!Наиболее распространённый вариант использования — initialize: подкласс принимает дополнительное значение, передаёт общие значения суперклассу с помощью super(...) и сохраняет собственное:
class Person
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
class Student < Person
attr_reader :school
def initialize(name, age, school)
super(name, age)
@school = school
end
end
s = Student.new("Ada", 20, "MIT")
puts "#{s.name}, #{s.age}, #{s.school}"Результат:
Ada, 20, MITТри формы различаются тем, что они передают. super без скобок передаёт те же аргументы, которые получил текущий метод; super() не передаёт аргументов; super(a, b) передаёт ровно указанные аргументы:
class Base
def show(*args)
"Base got #{args.inspect}"
end
end
class Child < Base
def show(a, b)
[super, super(), super(b)].join(" | ")
end
end
puts Child.new.show(1, 2)Вывод:
Base got [1, 2] | Base got [] | Base got [2]super может выполняться в любом месте метода или только при определённом условии. Если initialize подкласса принимает другие аргументы, чем метод родительского класса, одиночный super передаёт неправильные аргументы, что часто приводит к ошибке ArgumentError:
class Logger
def log(message)
puts "LOG #{message}"
end
end
class QuietLogger < Logger
def log(message)
super unless message.start_with?("debug")
end
end
logger = QuietLogger.new
logger.log("started")
logger.log("debug x=1")
logger.log("done")Вывод:
LOG started
LOG doneЗадание
ЛегкоДополните классы. Person хранит name и age, а его to_s возвращает Ada (36). Student добавляет школу: его initialize передаёт имя и возраст в super, а его to_s возвращает Ada (20), studies at MIT, построенное на основе super. Teacher таким же образом добавляет предмет и возвращает Bo (45), teaches maths.
Предоставленный код считывает строки person Ada 36, student Ada 20 MIT или teacher Bo 45 maths и выводит каждый объект.
Ваш код должен находиться в person.rb, student.rb и teacher.rb. В main.rb содержится предоставленный код ввода-вывода, и его нельзя редактировать.
Попробуйте сами
require_relative 'person'
require_relative 'student'
require_relative 'teacher'
# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, name, age, extra = line.split
person = case kind
when "student" then Student.new(name, age.to_i, extra)
when "teacher" then Teacher.new(name, age.to_i, extra)
else Person.new(name, age.to_i)
end
puts person
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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