Buscar..


Sintaxis

  • clase Subclase <SuperClase

Refactorizando las clases existentes para usar la herencia.

Digamos que tenemos dos clases, Cat y Dog .

class Cat
  def eat
    die unless has_food?
    self.food_amount -= 1
    self.hungry = false
  end
  def sound
    puts "Meow"
  end
end

class Dog
  def eat
    die unless has_food?
    self.food_amount -= 1
    self.hungry = false
  end
  def sound
    puts "Woof"
  end
end

El método de eat es exactamente el mismo en estas dos clases. Si bien esto funciona, es difícil de mantener. El problema empeorará si hay más animales con el mismo método de eat . La herencia puede resolver este problema.

class Animal
  def eat
    die unless has_food?
    self.food_amount -= 1
    self.hungry = false
  end
  # No sound method
end

class Cat < Animal
  def sound
    puts "Meow"
  end
end

class Dog < Animal
  def sound
    puts "Woof"
  end
end

Hemos creado una nueva clase, Animal , y hemos movido nuestro método de eat a esa clase. Luego, hicimos que Cat y Dog heredaran de esta nueva superclase común. Esto elimina la necesidad de repetir el código.

Herencia múltiple

La herencia múltiple es una característica que permite que una clase herede de varias clases (es decir, más de un padre). Ruby no admite herencia múltiple. Solo admite herencia simple (es decir, la clase solo puede tener un padre), pero puede usar la composición para crear clases más complejas utilizando módulos .

Subclases

La herencia permite que las clases definan un comportamiento específico basado en una clase existente.

class Animal
  def say_hello
    'Meep!'
  end

  def eat
    'Yumm!'
  end
end

class Dog < Animal
  def say_hello
    'Woof!'
  end
end

spot = Dog.new
spot.say_hello # 'Woof!'
spot.eat       # 'Yumm!'

En este ejemplo:

  • Dog hereda de Animal , haciéndolo una subclase .
  • Dog gana tanto el say_hello como el de eat de Animal .
  • Dog reemplaza el método say_hello con diferentes funcionalidades.

Mixins

Los mixins son una forma hermosa de lograr algo similar a la herencia múltiple. Nos permite heredar o, más bien, incluir métodos definidos en un módulo en una clase. Estos métodos pueden incluirse como métodos de instancia o de clase. El siguiente ejemplo muestra este diseño.

module SampleModule

  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods

    def method_static
      puts "This is a static method"
    end

  end

  def insta_method
    puts "This is an instance method"
  end

end

class SampleClass
  include SampleModule
end

sc = SampleClass.new

sc.insta_method

prints "This is an instance method"

sc.class.method_static

prints "This is a static method"

¿Qué se hereda?

Los métodos son heredados

class A
  def boo; p 'boo' end
end

class B < A; end

b = B.new
b.boo # => 'boo'

Los métodos de clase son heredados.

class A
  def self.boo; p 'boo' end
end

class B < A; end

p B.boo # => 'boo'

Las constantes son heredadas

class A
  WOO = 1
end

class B < A; end

p B::WOO # => 1

Pero cuidado, pueden ser anulados:

class B
  WOO = WOO + 1
end

p B::WOO # => 2

Las variables de instancia son heredadas:

class A
  attr_accessor :ho
  def initialize
    @ho = 'haha'
  end
end

class B < A; end

b = B.new
p b.ho # => 'haha'

Tenga cuidado, si anula los métodos que inicializan las variables de instancia sin llamar a super , serán nulos. Continuando desde arriba:

class C < A
  def initialize; end
 end

c = C.new
p c.ho    # => nil

Las variables de instancia de clase no se heredan:

class A
    @foo = 'foo'
    class << self
        attr_accessor :foo
    end
end

class B < A; end

p B.foo # => nil

# The accessor is inherited, since it is a class method
#
B.foo = 'fob' # possible

Las variables de clase no son realmente heredadas

Se comparten entre la clase base y todas las subclases como 1 variable:

class A
    @@foo = 0
    def initialize
        @@foo  += 1 
        p @@foo
    end
end

class B < A;end

a = A.new # => 1
b = B.new # => 2

Continuando desde arriba:

class C < A
  def initialize
    @@foo = -10
    p @@foo
  end
end

a = C.new # => -10
b = B.new # => -9


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow