Method Overriding

En la programación orientada a objetos, Method overriding es una característica del lenguaje que permita a una subclase proporcionar una implemetación específica de un método que ya existe en uno de sus ancestros. La implementación de la subclase reemplaza (overrides) al a implementación de la superclase.

Por ejemplo: p037xmtdovride.rb

 1 class A
 2   def a
 3     puts 'En la clase A'
 4   end
 5 end
 6 
 7 class B < A
 8   def a
 9     puts 'En la clase B'
10   end
11 end
12 
13 b = B.new
14 b.a

El método a en la clase B reemplaza al método a en la clase A.


Uso de super

La manera en que super maneja los argumentos es la siguiente:

  • Cuando invocas super sin argumentos, Ruby envía un mensaje a la superclase del objeto pidiéndole que invoque el método del mismo nombre que el método que invoca a super. Envía automáticamente los argumentos que fueron pasados al método desde el cual se llama a super.
  • Si es llamado con una lista de argumentos vacía super(), envía el mensaje sin argumentos al método del mismo nombre en la clase madre aun cuando hayan sido pasados argumentos al método desde que se invoca.
  • Si es llamado con argumentos específicos super(a,b,c), envía exactamente esos argumentos.

Un ejemplo del libro Ruby for Rails ilustra lo anterior (p038bicicleta.rb)

 1 class Bicicleta
 2   attr_reader :velocidades, :llantas, :asientos
 3   def initialize(velocidades = 1)
 4     @llantas = 2 
 5     @asientos = 1
 6     @velocidades = velocidades
 7   end
 8 end
 9 
10 class Tandem < Bicicleta
11   def initialize(velocidades)
12     super
13     @asientos = 2
14   end
15 end
16 t = Tandem.new(2)
17 puts t.velocidades
18 puts t.llantas
19 puts t.asientos
20 
21 b = Bicicleta.new
22 puts b.velocidades
23 puts b.llantas
24 puts b.asientos
Vamos a hablar con detenimiento acerca de attr_reader más adelante.

Redefiniendo métodos

(Adaptado del libre Ruby for Rails de David Black)

Nada nos impide definir un método dos veces. Observa el programa p038or.rb.

 1 class OR
 2   def mtd
 3     puts "Primera definición del método mtd"
 4   end
 5   
 6   def mtd
 7     puts "Segunda definición del método mtd"
 8   end
 9 end
10 
11 OR.new.mtd

El resultado imprime la segunda definición del método mtd. La segunda definición ha prevalecido.

Clases abstractas

En Ruby podemos definir una clase abstracta que invoque métodos indefinidos "abstractos" que son definidos sólo en las subclases.

 1 # Esta clase es abstracta; no define los métodos hola o nombre.
 2 # No es necesario utilizar sintaxis especial: cualquier clase que
 3 # invoca metodos que son definidos solo en las subclases es abstracta
 4 
 5 class ClaseAbstracta
 6   def bienvenida
 7     puts "#{hola} #{nombre}"
 8   end
 9 end
10 
11 # Una clase concreta:
12 
13 class ClaseConcreta < ClaseAbstracta
14   def hola; "Hola"; end
15   def nombre; "Estudiante de Ruby"; end
16 end
17 
18 ClaseConcreta.new.bienvenida