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 van Animal , waardoor het een Subklasse is .
  • Dog krijgt zowel de say_hello en eat methoden uit de Animal .
  • Dog overschrijft de methode say_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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow