Chamando super
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 24 de 57.
Dentro de um método sobrescrito, super chama a versão da superclasse do mesmo método. A subclasse pode aproveitar o resultado em vez de repeti-lo:
class Greeter
def greet(name)
"Hello, #{name}"
end
end
class LoudGreeter < Greeter
def greet(name)
super.upcase + "!"
end
end
puts LoudGreeter.new.greet("Ada")Saída:
HELLO, ADA!O uso mais comum é initialize: a subclasse recebe um valor extra, passa os valores compartilhados para a superclasse com super(...) e armazena o seu próprio:
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}"Saída:
Ada, 20, MITAs três formas diferem no que passam. super sem parênteses passa os mesmos argumentos que o método atual recebeu; super() não passa nenhum; super(a, b) passa exatamente estes:
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)Saída:
Base got [1, 2] | Base got [] | Base got [2]super pode ser executado em qualquer lugar do método ou somente sob uma condição. Quando o initialize da subclasse recebe argumentos diferentes dos da classe pai, o super simples passa os argumentos errados, gerando um ArgumentError comum:
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")Saída:
LOG started
LOG doneDesafio
FácilComplete as classes. Person armazena name e age, e seu to_s retorna Ada (36). Student adiciona uma escola: seu initialize passa o nome e a idade para super, e seu to_s retorna Ada (20), studies at MIT, construído a partir de super. Teacher adiciona uma disciplina da mesma forma e retorna Bo (45), teaches maths.
O código fornecido lê as linhas person Ada 36, student Ada 20 MIT ou teacher Bo 45 maths e imprime cada objeto.
Seu código deve ser colocado em person.rb, student.rb e teacher.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'person'
require_relative 'student'
require_relative 'teacher'
# Código de entrada/saída fornecido: mantenha-o como está
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
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de Ruby online