Szukaj…


Składnia

  • klasa SubClass <SuperClass

Refaktoryzacja istniejących klas pod kątem dziedziczenia

Powiedzmy, że mamy dwie klasy, Cat i 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

Metoda eat jest dokładnie taka sama w tych dwóch klasach. Chociaż to działa, trudno jest utrzymać. Problem pogorszy się, jeśli będzie więcej zwierząt z tą samą metodą eat . Dziedziczenie może rozwiązać ten 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

Stworzyliśmy nową klasę, Animal , i przenieśliśmy naszą metodę eat do tej klasy. Następnie sprawiliśmy, że Cat i Dog odziedziczyli tę nową powszechną nadklasę. Eliminuje to potrzebę powtarzania kodu

Wielokrotne dziedziczenie

Wielokrotne dziedziczenie to funkcja, która umożliwia jednej klasie dziedziczenie z wielu klas (tj. Więcej niż jednego rodzica). Ruby nie obsługuje wielokrotnego dziedziczenia. Obsługuje tylko pojedyncze dziedziczenie (tzn. Klasa może mieć tylko jednego rodzica), ale możesz użyć kompozycji do budowania bardziej złożonych klas za pomocą modułów .

Podklasy

Dziedziczenie pozwala klasom zdefiniować określone zachowanie w oparciu o istniejącą klasę.

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!'

W tym przykładzie:

  • Dog dziedziczy od Animal , co czyni go podklasą .
  • Dog zyskuje zarówno say_hello i eat metody Animal .
  • Dog zastępuje metodę say_hello z inną funkcjonalnością.

Mixiny

Mixiny to piękny sposób na osiągnięcie czegoś podobnego do wielokrotnego dziedziczenia. Pozwala nam dziedziczyć, a raczej włączać metody zdefiniowane w module do klasy. Metody te można uwzględnić jako metody instancji lub metody klasy. Poniższy przykład przedstawia ten projekt.

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"

Co jest dziedziczone?

Metody są dziedziczone

class A
  def boo; p 'boo' end
end

class B < A; end

b = B.new
b.boo # => 'boo'

Metody klasowe są dziedziczone

class A
  def self.boo; p 'boo' end
end

class B < A; end

p B.boo # => 'boo'

Stałe są dziedziczone

class A
  WOO = 1
end

class B < A; end

p B::WOO # => 1

Ale uwaga, można je zastąpić:

class B
  WOO = WOO + 1
end

p B::WOO # => 2

Zmienne instancji są dziedziczone:

class A
  attr_accessor :ho
  def initialize
    @ho = 'haha'
  end
end

class B < A; end

b = B.new
p b.ho # => 'haha'

Uwaga: jeśli zastąpisz metody inicjujące zmienne instancji bez wywoływania super , będą one zerowe. Kontynuując z góry:

class C < A
  def initialize; end
 end

c = C.new
p c.ho    # => nil

Zmienne instancji klasy nie są dziedziczone:

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

Zmienne klasowe nie są tak naprawdę dziedziczone

Są one dzielone między klasą podstawową i wszystkimi podklasami jako 1 zmienna:

class A
    @@foo = 0
    def initialize
        @@foo  += 1 
        p @@foo
    end
end

class B < A;end

a = A.new # => 1
b = B.new # => 2

Kontynuując z góry:

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow