Recherche…


Syntaxe

  • class SubClass <SuperClass

Refactoring des classes existantes pour utiliser l'héritage

Disons que nous avons deux classes, Cat et 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

La méthode de eat est exactement la même dans ces deux classes. Bien que cela fonctionne, il est difficile à maintenir. Le problème s'aggravera s'il y a plus d'animaux avec la même méthode de eat . L'héritage peut résoudre ce problème.

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

Nous avons créé une nouvelle classe, Animal , et avons déplacé notre méthode de eat à cette classe. Nous avons ensuite fait en sorte que Cat and Dog hérite de cette nouvelle superclasse commune. Cela supprime le besoin de répéter le code

Héritage multiple

L'héritage multiple est une fonctionnalité qui permet à une classe d'hériter de plusieurs classes (c.-à-d. Plusieurs parents). Ruby ne prend pas en charge l'héritage multiple. Il ne prend en charge que l'héritage simple (c.-à-d. Que la classe ne peut avoir qu'un seul parent), mais vous pouvez utiliser la composition pour créer des classes plus complexes à l'aide de modules .

Des sous-classes

L'héritage permet aux classes de définir un comportement spécifique basé sur une classe existante.

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!'

Dans cet exemple:

  • Dog hérite de l' Animal , ce qui en fait une sous - classe .
  • Dog acquiert à la fois les méthodes say_hello et eat de Animal .
  • Dog remplace la méthode say_hello avec différentes fonctionnalités.

Mixins

Les mixins sont un excellent moyen de réaliser quelque chose de similaire à l'héritage multiple. Cela nous permet d'hériter ou plutôt d'inclure des méthodes définies dans un module dans une classe. Ces méthodes peuvent être incluses en tant que méthodes d'instance ou de classe. L'exemple ci-dessous illustre cette conception.

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'est-ce qui est hérité?

Les méthodes sont héritées

class A
  def boo; p 'boo' end
end

class B < A; end

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

Les méthodes de classe sont héritées

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

class B < A; end

p B.boo # => 'boo'

Les constantes sont héritées

class A
  WOO = 1
end

class B < A; end

p B::WOO # => 1

Mais méfiez-vous, ils peuvent être remplacés:

class B
  WOO = WOO + 1
end

p B::WOO # => 2

Les variables d'instance sont héritées:

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

class B < A; end

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

Attention, si vous remplacez les méthodes qui initialisent les variables d’instance sans appeler super , elles seront nulles. En continuant d'en haut:

class C < A
  def initialize; end
 end

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

Les variables d'instance de classe ne sont pas héritées:

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

Les variables de classe ne sont pas vraiment héritées

Ils sont partagés entre la classe de base et toutes les sous-classes sous la forme d'une 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

Donc en continuant d'en haut:

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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow