Back to Home

 OOP Composition vs Inheritance

Feb 8, 2017

Be aware. This is heavy topic. Composition vs Inheritance is the topic that I would love to ignore and think as something that I've never have to worry about in real life. It's not that this is hard to understand or anything but I feel like it's not really useful in real life application. AND as always I WAS WRONG.

Designing object-oriented software is hard, and designing reusable object-oriented software is even harder.

Quick Conclusion and the Theory

In a composition-based system, the various components get combined togeter at run-time to create the desired behavior. This allows flexibility to build behavior dynamically without having to resort to clever metaprogramming tricks.

Composition has a few downsides too. It tends to add more indirection to a system. It can also be more work to assemble all the components together into the deesired behavior. Anything that can be implemented via inheritance can alternatively be implemented using composition.

Use inheritance when the cost of indirection and construction of a composition-based approach is higher than the benefits of encapsulated responsibilities and flexibilities.

Inheritance: Alter Before and After

So we all know how inheritance works. It inherites from parent class so the child can have exactly same behavior. For example:

class Parent def hello(person) puts "Dad, say hi to #{person}" end end class Child < Parent def hello(person) puts "Son, say hi to #{person}" super puts "Guesswhat, #{person}" end end son = Child.new son.hello('sister') => Son, say hi to sister Dad, say hi to sister Guesswhat, sister

super calls the same name method of the parent class, if it exists. Also it passes all the arguments to the parent class method as well.

using super() with initialize

class Parent def initialize(person) @person = person end def hello puts "Dad, say hi #{person} " end end class Child < Parent def initialize(person) @person = person super end end father = Parent.new("sister") son = Child.new("brother") son.hello => Dad, say hi brother

Composition

When to use compositon? Well, there is no right answer for it. Someone told me that composition is about behavior and inheritance is about state but that's very vague statement in my opinion. Both inheritance and composition are great way to DRY code. Here is simple example:

class Language def speak(type) if type == 'dog' puts 'I am hungry' elsif type == 'cat' puts'meow' end end end class Dog def initialize @language = Language.new end def bark @language.speak('dog') end end class Cat def initialize @language = Language.new end def meow @langauge.speak('cat') end end brian = Dog.new brian.bark => I am hungry

Perhaps this example does not really explan why we need to use language class instead of separate 'bark' and 'meow' function in the dog and cat classes but you can imagine this can be very useful when there are bunch of similar dog and cat classes and have similar behaviors. When ther eis change os how they speak, instead of visiting all classes, you can only change Language class.