Menu
Coddy logo textTech

Wywoływanie super

Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 24 z 57.

W metodzie przesłaniającej super wywołuje wersję tej samej metody z nadklasy. Podklasa może rozbudować wynik zamiast go powtarzać:

class Greeter
  def greet(name)
    "Hello, #{name}"
  end
end

class LoudGreeter < Greeter
  def greet(name)
    super.upcase + "!"
  end
end

puts LoudGreeter.new.greet("Ada")

Wynik:

HELLO, ADA!

Najczęściej używa się do tego initialize: podklasa przyjmuje dodatkową wartość, przekazuje wspólne wartości do nadklasy za pomocą super(...) i zapisuje własną:

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}"

Wynik:

Ada, 20, MIT

Te trzy formy różnią się tym, co przekazują. Samo super przekazuje te same argumenty, które otrzymała bieżąca metoda; super() nie przekazuje żadnych; super(a, b) przekazuje dokładnie te argumenty:

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)

Wynik:

Base got [1, 2] | Base got [] | Base got [2]

super może być uruchamiane w dowolnym miejscu metody lub tylko po spełnieniu warunku. Gdy initialize podklasy przyjmuje inne argumenty niż initialize klasy nadrzędnej, samo super przekazuje niewłaściwe argumenty, co często powoduje błąd 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")

Wynik:

LOG started
LOG done
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasy. Person przechowuje name i age, a jego metoda to_s zwraca Ada (36). Student dodaje szkołę: jego metoda initialize przekazuje imię i wiek do super, a jego metoda to_s zwraca Ada (20), studies at MIT, utworzone na podstawie super. Teacher dodaje w ten sam sposób przedmiot i zwraca Bo (45), teaches maths.

Dostarczony kod odczytuje wiersze person Ada 36, student Ada 20 MIT lub teacher Bo 45 maths i wypisuje każdy obiekt.

Twój kod umieść w plikach person.rb, student.rb i teacher.rb. main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

require_relative 'person'
require_relative 'student'
require_relative 'teacher'

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Ruby online