La herencia de clases es una relacción entre dos clases. La ventaja de la herencia es que las clases que en una jerarquía están en un nivel inferior, heredan las características de las clases de niveles superiores; y además, pueden añadir sus propias características.
Por ejemplo: todos los gatos son mamíferos. Si todos los mamíferos respiran, la clase gato por "descender" de la clase mamífero hereda esta característica: los gatos respiran.
Esto puede programarse así:
class Mamifero def respirar puts 'inspirar, espirar' end end # el símbolo < indica que # Gato es una subclase de Mamifero class Gato < Mamifero def maullar puts 'Miaaaaaaaaaaau' end end cribas = Gato.new cribas.respirar cribas.maullar
Aunque no se especificó que los gatos puedan respirar, todos los gatos herederán esa característica de la clase Mamifero, ya que el gato es una subclase de los Mamiferos. En el argot, Mamifero es la super-clase o clase padre, y Gato es la subclase, o clase hija. Esto es una ventaja para el programador: los gatos tienen la capacidad de respirar, sin haberlo implementado.
En Ruby, como se mostró en este esquema, la clase Object es la madre de todas las clases en Ruby; por lo tanto, sus métodos están disponibles en todos los objetos, excepto aquellos que se han sobrescrito.
Sobrescritura de métodos (method overriding)
Habrá situaciones donde las propiedades de una super-clase no deberían ser heredadas por una subclase en particular. Por ejemplo, las aves generalmente saben volar, pero los pingüinos son una subclase de Ave, y no vuelan:
class Ave def asear puts 'Me estoy limpiando mis plumas.' end def volar puts 'Estoy volando.' end end class Pinguino < Ave def volar puts 'Lo siento, no soy capaz de volar.' end end p = Pinguino.new p.asear p.volar
Se ha sobrescrito el método volar. La gran ventaja que aporta el uso de la herencia de clases, se llama programación diferencial: vamos de lo más general a lo más particular, añadiendo y modificando donde sea necesario.
Los dos ejemplos anteriores son traducciones de la guía online Ruby User's Guide
Super
class Bicicleta attr_reader :marchas, :ruedas, :asientos # se hablará de attr_reader def initialize(marchas = 1) @ruedas = 2 @asientos = 1 @marchas = marchas end end class Tandem < Bicicleta def initialize(marchas) super @asientos = 2 end end t = Tandem.new(2) puts t.marchas puts t.ruedas puts t.asientos b = Bicicleta.new puts b.marchas puts b.ruedas puts b.asientos
Cuando uno usa super dentro de un método, Ruby manda un mensaje a la clase madre del objeto al que pertence el método, buscando un método con el mismo nombre. Si:
- se invoca con una lista vacía de argumentos (como este caso), super ó super(), no se pasan argumentos al método de la clase madre.
- se invoca con argumentos, super(a, b, c), se mandand los argumentos a, b, c.
En este caso, se usa super en el método initialize de Tandem, lo que provoca el uso del initialize de Bicicleta para crear instancias de Tandem. La salida es:
2
2
2
1
2
1
RAILS: la herencia de clases es una de las claves en el desarrollo de RAILS