When to use inheritance?

I know we've all heard the phrase, "favor composition over inheritance"... and I try as much as I can to do that in my code. I'm wondering, though, when it makes sense to use inheritance over composition? Is there some rule to judge when something is a better fit for one over the other?

Whenever you see yourself reusing bits of code in different classes, or when some classes just require those bits of codes because they are pretty much meant to be extended versions of other classes, such as Person, Employee and Project Manager, which could all have a name (inherited from Person), salary (inherited from Employee which inherits the name from Person) and so forth.

Hope you got it. If not let me know and I'll try to explain further. smile

Object oriented theory has it that you should distinguish between is-a and has-a, to chose between inheritance and composition, but in practice this model soon breaks down. The problem is that the distinction isn't as black-and-white as it's made out to be; Real things get their meaning from a context, so when the context changes, they may change their meaning. Inheritance - being a static relationship - doesn't support this.

I'd say that it's a pragmatic choice. There are situations where it's just way more practical to use inheritance. Generally speaking though, it's mostly a hack. So from a purist point of view, I'll say that it's never better to use inheritance. In practice, well, some times you have to.

I don't know. I'll tell you one good thing about inheritance. When you don't know exactly what type of object you have stored in a variable, but you do know that it extends from Person so it must have at least a property named name, for example, then you can go over an entire database of people in different ranks and titles easily, because they'll all contain that name, since they extend person.

foreach($people as $person) echo $person->name;

Doesn't matter if it's a Person object, Employee object, ProjectManager or anything else that somewhere extends down to Person.

Class inheritance is a mix of two concepts. The extending class inherits the parents implementation (functions/methods) and it inherits the parents type. In a statically typed language, the latter is fairly important, since you can't freely mix types. So if some method expects an argument of a given type, you might use inheritance to satisfy this. In a dynamically typed language that is a non-issue. You can simply implement the expected behaviour and that's all there is to it. If you need a more explicit contract, you can document it or - since PHP has sort of a middle-way on this matter - you could use a statically typed interface (Eg. implements Person, rather than extends Person) to do the same thing. Since PHP is dynamically typed, this (slightly more verbose and restrictive) solution is purely optional. You can just use an implicit contract (duck typing).

The other use of class inheritance is to reuse implementation. If your abstract class Person is extended by a subclass Employer, you would have access to the same code in Employer as you do in Person. You could achieve code-reuse with composition as well, but it takes a bit more work. Employer would have to implement a wrapper that delegates control to a Person instance in this case. Eg.:

class Person {
  function sayHello() {
    echo "Hello, World!";
  }
}
class Employer {
  protected $person;
  function __construct() {
    $this->person = new Person();
  }
  function sayHello() {
    $this->person->sayHello();
  }
}

rather than:

class Person {
  function sayHello() {
    echo "Hello, World!";
  }
}
class Employer extends Person {}

As you can see, slightly more work to do, which is why people often use inheritance in these cases. The cost however, is that the Person-Employer relationship is now set in stone; It can't be changed or intercepted at runtime. There is also the matter of clarity. While the compositional code is more verbose, it is also very clear about what it does. You can look at the code and know what it does. With the inheritance version, you need to look at the superclass to find out what it does. Some times there are multiple levels of inheritance, making you trace up and down the chain to figure out exactly what code is available in the concrete class. Finally, there is the problem of multiple inheritance. In PHP, you can't. You only have one shot at inheritance, so if you want to reuse code from two places, well, you're out of luck.

For multiple level inheritance I use editors with code-insight. smile

By the way I personally never got stuck in a position where I wanted multiple inheritance. I find that avoiding it results in more organized, maintainable code.

And a perfect example for proper use of inheritance is the MVC structure, wouldn't you say? Creating a complex multi functional section is as easy as creating a class that extends from Controller. smile

A good use of inheritance I take advantage of is when you have a function you want to use in many classes, but want to make it quickly changable too.

An example is if you have a class with functions and properties you require in others:

<?php
class BaseObject{
    protected $id; //all objects may have an ID attatched to them
    function __Call($method, $params){ //allows you to get/set a public/protected using getVarName() - e.g. for $obj->bob it would be $obj->getBob() and $obj->setBob(...);
        $action = substr($method, 0, 3);
        $what = substr($method, 3);
        if(isset($this->$what)){
            $Obj =& $this->$what;
            switch($action){
                case 'get':
                    return $Obj;
                break;
                case 'set':
                    if(count($params) > 0){
                        return $Obj = $params[0];
                    }else{
                        return false;
                    }
                break;
            }
        }else{
            return false;
        }
        return false;
    }
}

Any class can now extend that and have the same functionality.

Yes, IDE's are good at that stuff. There are even better at it, if the language is statically typed. You could also turn that argument around and say that any language construct, that needs an IDE to keep you sane, is fundamentally flawed. But that's a matter of opinion.

I find that hard to believe. If you use inheritance as a vessel for code-reuse, then you will run into trouble, if your code isn't all stuffed into one single, giant GodClass.

Well, no. That's an example of good appliance of code-reuse. But you don't need to use inheritance to get code-reuse.

Again, this is code-reuse. You could do the same with delegation, even if it would have a slight bit of verbosity/redundancy. PHP doesn't support multiple inheritance, so creating base-classes like that, is a very bad idea. You either have to stuff all sorts of unrelated code into the same base-class, or you need to use delegation anyway and could as well have done so from the outset.

Can't say I agree with you. I guess it's a matter of opinion.

The .NET framework developers decided not to include multiple inheritance, and look, they have arguably the biggest most robust framework in the world. And everything is object-oriented.

Inheritance is a card you can only play once, and by choosing to make a "BaseObject" you have played your special card on the first hand without thinking.

Some other thoughts on the Inheritance vs. Composition debate: http://c2.com/cgi/wiki?CompositionInsteadOfInheritance

I don't quite follow you? Maybe you misunderstood what I was trying to say? I didn't suggest that you should use multiple inheritance, because - well - you can't. PHP doesn't allow it. What I meant was that if you use inheritance for code-reuse, then you can only ever reuse one piece of code. That's a severe limitation.

Inheritance is a card you can only play once, and by choosing to make a "BaseObject" you have played your special card on the first hand without thinking.

You can play that card in the parent class and simply extend that.

<?php
Class base{
	function sayHi(){
		return 'hi';
	}
}
Class James extends base{
	function __construct(){
		echo $this->sayHi();
	}
}
Class Bob extends James{
	function __construct(){
		echo $this->sayHi();
	}
}
new Bob();

I think the point is; what if James needs to extend a different class, Database for example, but then another class, Timothy, also needs to extend Database but doesn't need the functionality of Base?

And what if the parent class shouldn't include said aspect? Say you have these two generic classes:

class RegistryAccess {
  protected $registry;
  function __construct($registry) {
    $this->registry = $registry;
  }
  function __get($name) {
    return $this->registry->get($name);
  }
}
class Observable {
  protected $listeners = array();
  function connect($event, $observer) {
    $this->listeners[$event][] = $observer;
  }
  function signal($event) {
    foreach ($this->listeners[$event] as $observer) {
      $observer();
    }
  }
}

The first is a somewhat simpler variant of the class you have used already as an example. The latter is a pretty common pattern, that often gets implemented in some form, so I've made a generic implementation. Now, let's assume that you may not always want both things in your classes. Some times you need registryaccess and some times you don't. And some times you need an observable and some times you don't. Now you're stuck. You can't have your class Foo extend from both these generic classes, and making one of them extend the other doesn't make sense either, because that would

That would....?

I wouldn't see a problem with extending RegistryAccess to observable to extend functionality - but I do see what you mean.

So what would be your solution to a situation like this?

In your opinion, when would be the right time to play that "special card"?

Sometime third party software allows only this option for integration. For example, you subclass the Zend_Controller_Action in order to add your own controller if you are using the Zend Framework. You subclass definitely "Is A" controller, so it satisfies the "is a" vs. "has a" question on the correct side.

If you are in total control, go with the maxim "favor composition over inheritance".

BTW, There are design patterns which specify the use of inheritance. The whole "Template method" pattern is just following good subclassing practices. However, you will probably end up with a more flexible solution if you use the Strategy pattern instead.

BTW, There are design patterns which specify the use of inheritance. The whole "Template method" pattern is just following good subclassing practices. However, you will probably end up with a more flexible solution if you use the Strategy pattern instead.

There is one special thing with subclassing, compared to the strategy pattern.

With the strategy pattern you have a clear and fixed interface dictating what functionality depends on the strategy, and what functionality is fixed.

With inheritance, you can let the subclass decide which functionality it should override.

class Parent {
  function f() {
    $this->ff();
  }
  protected function ff() {
    $this->fff();
  }
  protected function fff();
}

class ChildA extends Parent {
  function fff() {...}
}

class ChildB extends Parent {
  function ff() {...}
}

class ChildC extends Parent {
  function f() {...}
}

If we want a strategy to be able to override f(), we have to add an explicit flex point in the parent class. With inheritance, this flex point comes (almost) for free.

So, the guideline I would suggest:

  • If you already know that there will be different alternatives, or if your class grows too big, make an explicit flex point for strategy / composition.
  • If overriding a specific method is too unlikely, and your class is small enough, then consider inheritance.

Hm, I hope that makes sense...

Any chance you could explain your reasoning behind using inheritance for your controllers in konstrukt? Was that simply an ease-of-use thing for people wanting to quickly use your framework?

I am looking at implementing a routing system that takes the place of your $map array and looks up subcontrollers in the database. (I want clients to be able to reorganize their content, so I'm keeping the "wire" that links all the controllers together in the db). I am attempting to implement this through composition so I can fully test each component, based on your handleRequest(), getNext(), forward(), etc. methods. It's proving to be a little tricky without inheritance, though.

Tough question. There are at least two reasons. First off, it's a matter of convenience. Konstrukt is a library, that is intended to be used by other programmers, so there need to be a clear interface, while still allowing a lot of flexibility. While you can get this with composition, it's also quite explicit. Normally this is a good thing, but for someone starting out with a library, it's perhaps a bit much. Especially considering that you would seldom need to use these hooks. Using inheritance makes it a bit easier on newcomers, because they don't need to be aware of as many of the inner workings as otherwise. In retrospect though, I'm not sure how well founded this is. In part, it was probably a semi-conscious choice at best, where I simply picked the simplest solution.

The other reason, is that a controller needs to both inherit implementation and interface (type), so that makes it a candidate for inheritance. In it self, this is probably not enough reason, but a controller is conceptually very tightly coupled to the framework. Even if the implementation decoupled it (Eg. through composition), it wouldn't really have any impact, because it doesn't make much sense to use a controller outside the context of the framework. So the implementation doesn't really take anything away in that sense. Arguably, this is a problem in it self, but I think it's inherently coupled with the whole concept of a framework in the first place. It is at least a recurring pattern, if you look at other similar frameworks. It would perhaps be interesting to try to break with this pattern. If you have been following the development of Konstrukt, then you'll see that that is exactly what happened to forms. In earlier versions, k_Form extended from k_Controller, but this has since changed so that today a k_Controller has a k_FormBehaviour.