Ruby Language
Héritage
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éthodessay_hello
eteat
deAnimal
. -
Dog
remplace la méthodesay_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