Ruby Language
Arv
Sök…
Syntax
- klass SubClass <SuperClass
Omfakturerar befintliga klasser för att använda Arv
Låt oss säga att vi har två klasser, Cat
och 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
eat
är exakt densamma i dessa två klasser. Medan detta fungerar är det svårt att underhålla. Problemet blir värre om det finns fler djur med samma eat
. Arv kan lösa detta problem.
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
Vi har skapat en ny klass, Animal
, och flyttat vår eat
till den klassen. Sedan fick vi Cat
och Dog
arva från denna nya gemensamma superklass. Detta tar bort behovet av att upprepa kod
Multipel ärft
Multipel arv är en funktion som gör att en klass kan ärva från flera klasser (dvs. mer än en förälder). Ruby stöder inte flera arv. Det stöder bara enarv (dvs. klass kan bara ha en förälder), men du kan använda komposition för att bygga mer komplexa klasser med moduler .
klasser
Arv gör det möjligt för klasser att definiera specifikt beteende baserat på en befintlig klass.
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!'
I detta exempel:
-
Dog
ärver frånAnimal
, vilket gör det en underklass. -
Dog
vinner bådesay_hello
ocheat
metoder frånAnimal
. -
Dog
åsidosättersay_hello
metoden med olika funktioner.
Mixins
Mixins är ett vackert sätt att uppnå något som liknar flera arv. Det tillåter oss att ärva eller snarare inkludera metoder definierade i en modul i en klass. Dessa metoder kan inkluderas antingen som instans- eller klassmetoder. Nedanstående exempel visar denna design.
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"
Vad ärvs?
Metoder ärvs
class A
def boo; p 'boo' end
end
class B < A; end
b = B.new
b.boo # => 'boo'
Klassmetoder ärvs
class A
def self.boo; p 'boo' end
end
class B < A; end
p B.boo # => 'boo'
Konstanter ärvs
class A
WOO = 1
end
class B < A; end
p B::WOO # => 1
Men se upp, de kan åsidosättas:
class B
WOO = WOO + 1
end
p B::WOO # => 2
Instansvariabler ärvs:
class A
attr_accessor :ho
def initialize
@ho = 'haha'
end
end
class B < A; end
b = B.new
p b.ho # => 'haha'
Se upp, om du åsidosätter de metoder som initialiserar instansvariabler utan att kalla super
, kommer de att vara noll. Fortsätter från ovan:
class C < A
def initialize; end
end
c = C.new
p c.ho # => nil
Klassinstansvariabler ärvs inte:
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
Klassvariabler ärvs inte riktigt
De delas mellan basklassen och alla underklasser som en variabel:
class A
@@foo = 0
def initialize
@@foo += 1
p @@foo
end
end
class B < A;end
a = A.new # => 1
b = B.new # => 2
Så fortsätter från ovan:
class C < A
def initialize
@@foo = -10
p @@foo
end
end
a = C.new # => -10
b = B.new # => -9