Поиск…


Синтаксис

  • класс SubClass <SuperClass

Рефакторинг существующих классов для использования Наследование

Предположим, у нас есть два класса: Cat и 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 точно такой же в этих двух классах. Хотя это работает, его трудно поддерживать. Проблема будет ухудшаться, если есть больше животных с тем же методом eat . Наследование может решить эту проблему.

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

Мы создали новый класс, Animal , и перевели наш метод eat в этот класс. Затем мы заставили Cat и Dog наследовать этот новый общий суперкласс. Это устраняет необходимость повторения кода

Многократное наследование

Множественное наследование - это функция, позволяющая одному классу наследовать от нескольких классов (т. Е. Более одного родителя). Ruby не поддерживает множественное наследование. Он поддерживает только однонаследование (т.е. класс может иметь только один родительский элемент), но вы можете использовать композицию для построения более сложных классов с использованием модулей .

Подклассы

Наследование позволяет классам определять конкретное поведение на основе существующего класса.

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

В этом примере:

  • Dog наследует от Animal , делая ее подклассом .
  • Dog получает как say_hello и eat методы от Animal .
  • Dog переопределяет метод say_hello с разной функциональностью.

Примеси

Mixins - прекрасный способ добиться чего-то подобного множественному наследованию. Это позволяет нам наследовать или, скорее, включать методы, определенные в модуле в класс. Эти методы могут быть включены как методы экземпляра или класса. В приведенном ниже примере изображена эта конструкция.

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"

Что унаследовано?

Методы наследуются

class A
  def boo; p 'boo' end
end

class B < A; end

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

Методы класса унаследованы

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

class B < A; end

p B.boo # => 'boo'

Константы унаследованы

class A
  WOO = 1
end

class B < A; end

p B::WOO # => 1

Но будьте осторожны, их можно переопределить:

class B
  WOO = WOO + 1
end

p B::WOO # => 2

Переменные экземпляра наследуются:

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

class B < A; end

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

Опасайтесь, если вы переопределите методы, которые инициализируют переменные экземпляра без вызова super , они будут равны нулю. Продолжая сверху:

class C < A
  def initialize; end
 end

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

Переменные экземпляра класса не наследуются:

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

Переменные класса на самом деле не унаследованы

Они распределяются между базовым классом и всеми подклассами как 1 переменная:

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

class B < A;end

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

Итак, продолжая сверху:

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow