Re: Struggling with liskov substitution principle (again).

From: Date: Tue, 22 Jul 2014 23:08:09 +0000
Subject: Re: Struggling with liskov substitution principle (again).
References: 1  Groups: php.general 
Request: Send a blank email to php-general+get-323646@lists.php.net to get a copy of this message
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

« previous php.general (#323646) next »