Class, Modules and Mixin

To inherit is to acquire from somewhwere, you can inherit you mother looks, your fathers strictness which maybe he is inherited from is from father before him.

Inheritance is a kind of downward-chaining relationship between two classes (the super-class and the subclass), whereby one class “inherits” from another and the instances ofthe subclass acquire the behaviors—the methods—defined in the superclass.

Inheritance in classes

A class acquire propeties of other class, the who is the owner of these traits is known as super class while the one inheriting the properties(methods) is known as sub class.Think of super class as your father and subclass as you.

Let say we are classifying living things, we put all animals together in a class Animals and have a class like so:

1
2
3
4
5
6
7
8
9
class Animal
    def reproduction
        "They reproduce"
    end
    def motion
        "capable of motion"
    end

end

Create a file classification.rb and add the code above.

Let us say our classification has gone deep down and now we are at point where the we have to group traits that are similar together and octopus call this grouping octopus.These traits were: - reproduce - motion - swim Our class(group) would be like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Octopus
    def reproduction
        "They reproduce"
    end
    def motion
        "capable of motion"
    end
    def swim
        "can swim"
    end


end

You realize that the traits of Octupus duplicate traits of Animals.In spirit of Keeping code dry and code reuse, is not what we want.Since Octopu is an animal it has traits of Animal and can inherit from it like so:

Let's use edit classification.rb by adding class Dog like

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Animal
    ...
    ...
end

class Octopus < Animal
    def swim
        "can swim"
    end

end

shaggy = Octopus.new
puts shaggy.reproduce
1
2
$ ruby animal.rb
$ can reproduce

When we ask shaggy(Octopus)instance of wether it know reproduces it respond graciously

The Class Octopus has the behavors of the animal that is the power of inheritance.

Overiding methods

Lets our animal is capable of dying.So let edit classification.rb to that method.

1
2
3
4
5
6
7
class Animal
    ...
    ...
    def die
     "can die naturally"
    end
end

What of Octopus, by the way this is fun a fact octupus do not die natural death.When we ask octupus to die it "says die naturally" but that is not true.From fun fact we realized that Octopus do not die naturally.So what we do worry not ruby got you covered.We can change response of Octopus.This is known as method over ride.Let us do that.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Animal
    ...
    ...
    def die
     "can die naturally"
    end
end 
class Octopus < Animal
    def die
    "do not die naturally"
    end

end

shaggy = Octupus.new
shaggy.die
1
2
$ ruby classification.rb
$ do not die naturally

Exercise

  • create a class CentralGovernment with methods taxes, corrects, enforce_laws(should have default parameter of value, "Fairly"), depending on your view on central government, define the above methods with return value being how think you central government perform them.

  • Create another class CountyGovernment that inherits from class CentralGovernment.

  • CountyGovernment should not enforce national laws override return value of enforce_laws to be "Should only enforce county laws" in CountyGovernmentclass.

Modules

Lets think for about our classification for a minute Octupus is an Animals and Animal is LivingThing.Therefore we can say class LivingThing is super class of class Animals.Let us create class LivingThings like so: edit classifaiction.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class LivingThing

    def survival
        "Adaptation through evolution"
    end

end
class Animal 
...
...
end
class Octopus<Animal
...
end

Since inheritance is down chain class Animal could inherit from LivingThing which in turn inherits and Octupus could inherit from Animal therefore having traits of LivingThing in the process.But what if we wanted to multi-inheritance, that is Octopus inheriting from Animal and LivingThing and the same time like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class LivingThing
...
end
class Animal
...
..
end
class < Animal < LivingThing
...
end

Well above code throws an error, multi-inheritance is not possible in class in ruby, so what do we do that where modules come in.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Module LivingThing
    def survival
        "Adaptation through evolution"
    end
end

class Animal 
    def motion
        "capable of motion"
    end
    def swim
        "can swim"
    end
    def die
    "can die naturally"
    end
end

class Octopus < Animal
    include LivingThing
    def die
    "do not die naturally"
    end
end

Now Octupus have all traits of LivingThing try asking an instance of Octopus if it respond to
swim

The core difference between a module it allows multiple inheritance while class do not. On other hand while class you can create instance(that is object) you cannot do so with module

Method Lookup Path

Now that you have a grasp on both inheritance and mixins. Let's put them both together to see how that affects the method lookup path. The method lookup path is the order in which classes are inspected when you call a method.

method_lookup_path.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
module Swimmable
  def swim
    "I'm swimming."
  end
end

module Climbable
  def climb
    "I'm climbing."
  end
end

class Animal
  include Walkable

  def speak
    "I'm an animal, and I speak!"
  end
end
puts Animal.ancestors
1
ruby method_lookup_path.rb

The method lookup path is the path Ruby takes to look for a method. We can see this path with the ancestors class method.

This means that when we call a method of any Animal object, first Ruby looks in the Animal class, then the Walkable module, then the Object class, then the Kernel module, and finally the BasicObject class.

### Extend,Include,Prepend

Inorder for you to add module inheritance we used include the module.When you use include the methods in a class are the first to be considered then those in module but when you use prepend module methods are considered first before module methods. Extend add module methods not as instance methods but as class methods in whatever class it add

#### Exercise

  • Replace include Walkable in method_lookup_path.rb with prepend Walkable and run the file and compare the outputs