Menu
Coddy logo textTech

Ridefinizione dei metodi

Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 23 di 57.

Una sottoclasse può ridefinire un metodo definendone uno con lo stesso nome. Ruby cerca prima un metodo nella classe dell'oggetto e solo in seguito nella superclasse, quindi prevale la versione della sottoclasse:

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

Output:

Woof
...

Un metodo della superclasse che chiama un altro metodo usa la versione sovrascritta per gli oggetti della sottoclasse. Il metodo condiviso viene scritto una sola volta e ogni sottoclasse modifica solo la parte che differisce:

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

Output:

Tom says Meow
Thing says ...

Ridefinire to_s in una sottoclasse cambia il modo in cui viene stampata solo quella sottoclasse. I metodi che non ridefinisce continuano a provenire dalla superclasse:

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)

Output:

Lamp 20.00
Lamp 16.00 (sale)

L'ordine in cui Ruby cerca è quello degli antenati della classe: la classe stessa, poi la sua superclasse e così via fino a Object. La prima classe nell'elenco che definisce il metodo lo fornisce:

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)

Output:

Woof
[Puppy, Dog, Animal]
challenge icon

Sfida

Facile

Completa le classi per le buste paga. Employee memorizza un name e ha pay(hours), che restituisce hours * 20, e payslip(hours), che restituisce Ada: 800 usando pay. Manager sovrascrive pay con un valore fisso di 1500, indipendentemente dalle ore. Intern sovrascrive pay con hours * 12, ma al massimo 300. payslip è definito solo in Employee.

Il codice fornito legge righe come employee Ada 40, manager Bo 50 o intern Cy 20, crea l'oggetto corrispondente e ne stampa la busta paga, poi stampa il totale dei compensi.

Il tuo codice va in employee.rb, manager.rb e intern.rb. main.rb contiene il codice fornito per l'input/output e non può essere modificato.

Provalo tu

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

# Supplied input/output code: keep it as it is
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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Ruby online