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ån Animal , vilket gör det en underklass.
  • Dog vinner både say_hello och eat metoder från Animal .
  • Dog åsidosätter say_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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow