Ruby Language
Erfenis
Zoeken…
Syntaxis
- klasse SubClass <SuperClass
Refactoring van bestaande klassen om overerving te gebruiken
Laten we zeggen dat we twee klassen hebben, Cat
en 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
De eat
is precies hetzelfde in deze twee klassen. Hoewel dit werkt, is het moeilijk te onderhouden. Het probleem wordt erger als er meer dieren zijn met dezelfde eat
. Overerving kan dit probleem oplossen.
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
We hebben een nieuwe klas, Animal
, gemaakt en onze eat
naar die klas verplaatst. Daarna lieten we Cat
and Dog
erven van deze nieuwe gemeenschappelijke superklasse. Hierdoor is het niet meer nodig om code te herhalen
Meerdere overerving
Meervoudige overerving is een functie waarmee één klasse kan erven van meerdere klassen (dat wil zeggen, meer dan één ouder). Ruby ondersteunt geen meervoudige overerving. Het ondersteunt alleen single-inheritance (klasse kan dus maar één ouder hebben), maar u kunt compositie gebruiken om complexere klassen te bouwen met behulp van modules .
subklassen
Door overerving kunnen klassen specifiek gedrag definiëren op basis van een bestaande klasse.
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!'
In dit voorbeeld:
-
Dog
Erft vanAnimal
, waardoor het een Subklasse is . -
Dog
krijgt zowel desay_hello
eneat
methoden uit deAnimal
. -
Dog
overschrijft de methodesay_hello
met verschillende functies.
mixins
Mixins zijn een prachtige manier om iets vergelijkbaars te bereiken met multiple erfenis. Het stelt ons in staat om methoden die in een module zijn gedefinieerd over te nemen naar een klasse. Deze methoden kunnen worden opgenomen als instantie- of klassenmethode. Het onderstaande voorbeeld geeft dit ontwerp weer.
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"
Wat is erfelijk?
Methoden zijn geërfd
class A
def boo; p 'boo' end
end
class B < A; end
b = B.new
b.boo # => 'boo'
Klasse methoden zijn geërfd
class A
def self.boo; p 'boo' end
end
class B < A; end
p B.boo # => 'boo'
Constanten zijn geërfd
class A
WOO = 1
end
class B < A; end
p B::WOO # => 1
Maar pas op, ze kunnen worden opgeheven:
class B
WOO = WOO + 1
end
p B::WOO # => 2
Instantievariabelen zijn overgenomen:
class A
attr_accessor :ho
def initialize
@ho = 'haha'
end
end
class B < A; end
b = B.new
p b.ho # => 'haha'
Let op, als u de methoden die instantievariabelen initialiseren negeren zonder super
te roepen, zijn ze nul. Voortgaand van boven:
class C < A
def initialize; end
end
c = C.new
p c.ho # => nil
Varianten van klasseninstanties worden niet geërfd:
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
Klasse variabelen zijn niet echt geërfd
Ze worden gedeeld tussen de basisklasse en alle subklassen als 1 variabele:
class A
@@foo = 0
def initialize
@@foo += 1
p @@foo
end
end
class B < A;end
a = A.new # => 1
b = B.new # => 2
Dus verdergaand van boven:
class C < A
def initialize
@@foo = -10
p @@foo
end
end
a = C.new # => -10
b = B.new # => -9