Menu
Coddy logo textTech

Nadpisywanie metod

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

Podklasa może przesłonić metodę, definiując metodę o tej samej nazwie. Ruby najpierw szuka metody w klasie danego obiektu, a dopiero potem w nadklasie, więc wygrywa wersja z podklasy:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Fish < Animal
end

puts Dog.new.speak
puts Fish.new.speak

Wynik:

Woof
...

Metoda nadklasy, która wywołuje inną metodę, używa nadpisanej wersji dla obiektów podklasy. Wspólna metoda jest zapisana tylko raz, a każda podklasa zmienia tylko tę część, która się różni:

class Animal
  def initialize(name)
    @name = name
  end

  def introduce
    "#{@name} says #{speak}"
  end

  def speak
    "..."
  end
end

class Cat < Animal
  def speak
    "Meow"
  end
end

puts Cat.new("Tom").introduce
puts Animal.new("Thing").introduce

Wynik:

Tom says Meow
Thing says ...

Nadpisanie to_s w podklasie zmienia sposób wyświetlania tylko tej podklasy. Metody, których nie nadpisuje, nadal pochodzą z nadklasy:

class Item
  def initialize(name, price)
    @name = name
    @price = price
  end

  def to_s
    format("%s %.2f", @name, @price)
  end
end

class SaleItem < Item
  def to_s
    format("%s %.2f (sale)", @name, @price * 0.8)
  end
end

puts Item.new("Lamp", 20)
puts SaleItem.new("Lamp", 20)

Wynik:

Lamp 20.00
Lamp 16.00 (sale)

Kolejność, w jakiej Ruby wyszukuje metodę, wyznaczają przodkowie klasy: sama klasa, następnie jej nadklasa i tak dalej, aż do Object. Pierwsza klasa na tej liście, która definiuje metodę, udostępnia ją:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Puppy < Dog
end

puts Puppy.new.speak
p Puppy.ancestors.take(3)

Wynik:

Woof
[Puppy, Dog, Animal]
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasy płacowe. Employee przechowuje name i ma metodę pay(hours), która zwraca hours * 20, oraz metodę payslip(hours), która zwraca Ada: 800, używając pay. Manager nadpisuje pay, zwracając zawsze stałą wartość 1500, niezależnie od liczby godzin. Intern nadpisuje pay, zwracając hours * 12, ale najwyżej 300. payslip jest zdefiniowana tylko w Employee.

Dostarczony kod odczytuje wiersze employee Ada 40, manager Bo 50 lub intern Cy 20, tworzy pasujący obiekt i wyświetla jego pasek płacowy, a następnie wyświetla łączną kwotę wypłat.

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

Spróbuj swoich sił

require_relative 'employee'
require_relative 'manager'
require_relative 'intern'

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "employee" => Employee, "manager" => Manager, "intern" => Intern }
total = 0
input.each do |line|
  kind, name, hours = line.split
  worker = kinds[kind].new(name)
  puts worker.payslip(hours.to_i)
  total += worker.pay(hours.to_i)
end
puts "total: #{total}"
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