Inheritance
Subclasses
Section titled “Subclasses”Inheritance allows classes to define specific behaviour based on an existing class.
class Animal def say_hello 'Meep!' end
def eat 'Yumm!' endend
class Dog < Animal def say_hello 'Woof!' endend
spot = Dog.newspot.say_hello # 'Woof!'spot.eat # 'Yumm!'In this example:
DogInherits fromAnimal, making it a Subclass.Doggains both thesay_helloandeatmethods fromAnimal.Dogoverrides thesay_hellomethod with different functionality.
Multiple Inheritance
Section titled “Multiple Inheritance”Multiple inheritance is a feature that allows one class to inherit from multiple classes(i.e., more than one parent). Ruby does not support multiple inheritance. It only supports single-inheritance (i.e. class can have only one parent), but you can use composition to build more complex classes using Modules.
What is inherited?
Section titled “What is inherited?”Methods are inherited
class A def boo; p 'boo' endend
class B < A; end
b = B.newb.boo # => 'boo'Class methods are inherited
class A def self.boo; p 'boo' endend
class B < A; end
p B.boo # => 'boo'Constants are inherited
class A WOO = 1end
class B < A; end
p B::WOO # => 1But beware, they can be overridden:
class B WOO = WOO + 1end
p B::WOO # => 2Instance variables are inherited:
class A attr_accessor :ho def initialize @ho = 'haha' endend
class B < A; end
b = B.newp b.ho # => 'haha'Beware, if you override the methods that initialize instance variables without calling super, they will be nil. Continuing from above:
class C < A def initialize; end end
c = C.newp c.ho # => nilClass instance variables are not inherited:
class A @foo = 'foo' class << self attr_accessor :foo endend
class B < A; end
p B.foo # => nil
# The accessor is inherited, since it is a class method#B.foo = 'fob' # possibleClass variables aren’t really inherited
They are shared between the base class and all subclasses as 1 variable:
class A @@foo = 0 def initialize @@foo += 1 p @@foo endend
class B < A;end
a = A.new # => 1b = B.new # => 2So continuing from above:
class C < A def initialize @@foo = -10 p @@foo endend
a = C.new # => -10b = B.new # => -9Mixins
Section titled “Mixins”Mixins are a beautiful way to achieve something similar to multiple inheritance. It allows us to inherit or rather include methods defined in a module into a class. These methods can be included as either instance or class methods. The below example depicts this 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 SampleModuleend
sc = SampleClass.new
sc.insta_method
prints "This is an instance method"
sc.class.method_static
prints "This is a static method"Refactoring existing classes to use Inheritance
Section titled “Refactoring existing classes to use Inheritance”Let’s say we have two classes, Cat and Dog.
class Cat def eat die unless has_food? self.food_amount -= 1 self.hungry = false end def sound puts "Meow" endend
class Dog def eat die unless has_food? self.food_amount -= 1 self.hungry = false end def sound puts "Woof" endendThe eat method is exactly the same in these two classes. While this works, it is hard to maintain. The problem will get worse if there are more animals with the same eat method. Inheritance can solve this problem.
class Animal def eat die unless has_food? self.food_amount -= 1 self.hungry = false end # No sound methodend
class Cat < Animal def sound puts "Meow" endend
class Dog < Animal def sound puts "Woof" endendWe have created a new class, Animal, and moved our eat method to that class. Then, we made Cat and Dog inherit from this new common superclass. This removes the need for repeating code
Syntax
Section titled “Syntax”- class SubClass < SuperClass