Re: Struggling with liskov substitution principle (again).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Richard Quadling wrote:

> If I have a method that requires a piece of fruit. And I have a base fruit
> object that has all the properties and methods I need to operate upon it at
> the general level, why can't I extend that into a apples and oranges and
> extend the controller (appleController, orangeController) both of which are
> based upon fruitController (that layer wants fruit - be it apples, oranges
> or pears or anything that extends fruit).

In your case the Liskov Substition Principle is all about
*contravariant* parameter/argument types.  There is a nice article
available at
<http://www.gnu.org/software/sather/docs-1.2/tutorial/type-conformance.html>,
which helped me to understand this issue.

They are using a very descriptive example, using omnivores, herbivores
and carnivores.  At a first glance, it seems reasonable to make
herbivores and carnivores a subtype of omnivores (among others, both can
eat).  Obviously, meat and plants are a subtype of food, so one can
think of:

    class Food {}
    class Plant extends Food {}
    class Meat extends Food {}

    class Omnivore {
        function eat(Food $food) {}
    }
    class Herbivore extends Omnivore {
        function eat(Plant $plant) {}
    }
    class Carnivore extends Omnivore {
        function eat(Meat $meat) {}
    }

However, that doesn't work out.  Consider an animal of type Omnivore,
which is actually a cow.  According to the definition of Omnivore, you
can feed it any food--but surely the cow won't eat meat!  This is why
PHP emits a "strict" warning for the code above.

Actually, the problem is that this subtyping relationship is not an
*is-a* relationship (neither a herbivore nor a carnivore is an
omnivore).  The same holds for your example: neither an appleController
nor an orangeController is a fruitController, because they only can deal
with apples resp. oranges, but not general fruits.

IMHO, this simple *is-a* relationship explains it all: an apple *is a*
fruit, and an orange *is a* fruit.  However, an apple juicer as well as
an orange juicer *is not a* fruit juicer (at least not necessarily).

-- 
Christoph M. Becker

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php





[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux