Liskov substitution principle and multiple hierarchies - java

This question is a follow up to this. I am trying to define class heirarchies involving multiple base-derived pairs. As an illustrative example, suppose that I have a class Animal and a class Food. Animal has a pure virtual function to mark its food preference, taking a food as parameter.
class Food
{
public:
virtual void printName() {
//......
}
};
class Animal
{
public:
Food *_preferredFood;
virtual void setFoodPreference(Food *food)=0;
};
I need to write code that deals only with these base classes, and calls the pure virtual function. For example, I have a ZooManager class, which sets food preferences for each animal.
class ZooManager
{
vector<Aninal*> animals;
public:
void setAllPreferences(vector<Food *> foods) {
assert(animals.size() == foods.size());
for(int i =0;i<animals.size();i++) {
animals[i]->setFoodPreference(foods[i]);
}
}
};
So far so good. Now the problem is, that there are many different derived classes for Food and Animal. Food has derived classes Fruit and Meat, and Animal has derived classes Carnivore and Herbivore. Herbivore can accept only Fruit as food preference, and Carnivore can accept only Meat.
class Fruit : public Food
{
};
class Meat : public Food
{
};
class Carnivore: public Animal
{
public:
void setFoodPreference(Food *food) {
this->_preferredFood = dynamic_cast<Meat *>(food);
}
};
class Herbivore: public Animal
{
public:
void setFoodPreference(Food *food) {
this->_preferredFood = dynamic_cast<Fruit *>(food);
}
};
Can I create a class heirarchy for this without violating Liskov Substitution Principle? Although I use C++ in this question, I'd welcome Java-specific answers too.

First, your setFoodPreference has to have the option to fail. That lets setFoodPreference take a Food* and have the postcondition of either setting the food preference, or failing.
The dynamic cast can also be a failure of LSP, but if you arrange your type invariants to be vague enough it isn't technically a failure.
Generally, dynamic_cast means that the type of the argument passed and its properties isn't sufficient to tell if the argument has certain properties.
In principle, setFoodPreference(Food*) should be specified in terms of what Food* properties the passed in argument has to have in order for the setting to be successful; the dynamic type of the Food* is not a Food* property.
So: LSP states that any subclass of Food has to obey all Food invariants. Similarly for Animal. You can avoid a LSP violation by making the invariants vague and the behavior of methods unpredictable; basically by saying "it can fail for unspecified reasons". This is ... not very satisfying.
Now, you can take a step back and decide that the dynamic type of your Food* is part of the Food*'s interface; that makes the interface ridiculously broad, and makes a mockery of LSP.
The point of LSP is that you can reason about a Food* without having to think about its subclass types; they are "how it works as a Food". Your code binds tightly to the subclass types, and thus bypasses the point of LSP.
There are ways around this. If Food had an enum stating what kind of food it was, and you never dynamically cast down to Meat but rather asked the Food if it was meat, you avoid it. Now you can specify setFoodPreference's behavior in terms of Food's interface.

Your approach to designing your hierarchies is wrong. OO classes represent groups of tightly coupled rules, where a rule is a function and tightly coupled means shared data. OO classes do NOT represent real world objects. People are wrong when they say that.
If you are depending on the concrete type of Food, you are violating the Liskov substitution principle. Period.
To design your classes correctly so that you are not forced into violating the LSP as you are here, you need to place rules in the Food class that can be used by the Animal class to accomplish its own rules. Or decide whether Food should even be a class. What your example shows is basically really bad String comparison.

Related

How can I make a method with a bounded type parameter exclude one subclass?

Let us assume that gibbons, orangutans, gorillas, chimpanzees and humans are all apes. I have modeled this relationship accordingly.
class Ape {}
class Gibbon extends Ape {}
class Orangutan extends Ape {}
class Gorilla extends Ape {}
class Chimpanzee extends Ape {}
class Human extends Ape {}
I now want to write a hunt() method with a bounded type parameter for hunting apes.
public static <T extends Ape> void hunt(T type) {}
Let us assume that there is nothing wrong with hunting non-human apes because they are just animals. However, hunting humans is wrong because it is murder. How can I re-write the above bounded type parameter to exclude humans as a legal parameter? I am not interested in exceptions here. I do not want the hunt() method to compile at all if invoked with a human parameter.
You can't exclude a specific subclass the way you intend there. What you can do however, is create an interface 'isHuntable', implemented by the required animals you want to hunt, and you use that as a type for your method instead of the generic type bound. Another maybe less elegant solution is to create another level in your hierarchy called 'Monkeys' for example which extend from Ape, having all the animals extending from it, and you use that Monkey type for your method. I'd go with the first approach though. You could use explicit type checking, but you'd be breaking the 'open-closed' principle in you code, so it's better to leverage those checks to the type system.
Just extending a bit on the concept of interface behaviour-contract which is powerful tool which is sadly underused. What you have among your Apes is a "is-a" relationship which tightly couples your subjects. Being "Huntable" on the other hand, is not an inherent or defining characteristic of the structure of that hierarchy, and is more an added condition/behaviour/check you'd like to add to a subset of that hierarchy. That is better achieved by adding contracts (interface implementation) to the subset you intend to have that behaviour. That will allow to add further contracts (interface implementations) in the future with minimal refactorings, maximal semantic clarity, less bugs and without tightly bounding a type to a behaviour. In short, you don't break the Liskov Substitution principle, nor the open closed principle, nor any SOLID principle.
I don't believe there's a way to do this. You could make a sub-type of Ape that excludes Humans, or you can check for Humans as a type in the method itself (which would violate the Open-Closed principle) :
public static <T extends Ape> void hunt(T type) {
if (type instanceOf Human) {
throw new IllegalArgumentException("It's immoral to hunt Humans. You monster.");
}
. . .
}
You cannot do this. There is no way to specify a bound to say "any subclass, except this one".
And even if you could, it wouldn't stop you invoking it:
chimp.hunt((Ape) human);
would get around it.
All you can do is to check this at runtime.
You could, via some tool such as Error Prone (written by Google, I am an employee, and I contribute; other tools are available) write a compile-time check to ensure that the argument is neither Ape nor Human; but that's outside the capabilities of "pure" Java.
I would make your hunt method non-static; it's an action on the object itself, after all. Then, you can define the behavior for all Apes:
public void hunt() {
this.die(); // oh no!
}
And of course, humans override that basic idea:
#Override
public void hunt() {
throw new IllegalMurderException("Human horn hunting is against intergalactic law");
}
Adding a check for #isHuntable would be advisable, as keeping with the metaphor it's nice to know if you're allowed to hunt something before doing so. Additionally, I went with an exception for human hunting as it violates the general behavior of what you (well, I) would expect #hunt to achieve.
For the sake of overengineering and various concepts of SOLID, you can achieve this with a Huntable interface, which could extend a Living interface:
public interface Living {
public void die();
}
public interface Huntable extends Living {
default public void hunt() {
this.die();
}
//could use this for a generic exception in the interface too
public boolean isHuntable();
}
public interface Ape extends Huntable {} // already Huntable
public interface Human extends Ape {
//And finally, we break that behavioral contract like above
}
Overall this makes your generics unnecessary. You'll be forced into a type cast and manual check if you go that route, as other answers have shown. So while it sidesteps the original question, I think this is a better solution to the underlying problem (XY problem?). More importantly, behavior concerning humans remains in a class describing humans.
Edit:
In keeping with the static method and a checked exception, while I strongly recommend against it (per my comments), you can use a method overload so Human objects go through a different signature:
public static void hunt(Ape example) { ... }
public static void hunt(Human example) throws HuntingException {
throw new HuntingException("cannot hunt humans");
}
HuntingException would extend Exception instead of RuntimeException. Exception/Error/Throwable objects that you make yourself are all essentially checked exceptions. Short of that, there's no creating compiler errors yourself as a developer. You can generate warnings, but you face the same pitfalls.
You can kind of see why this is silly, and a human is still able to be hunted without a compiler error at all by just casting:
Main.hunt((Ape) someHuman);
So now you go back down the rabbit hole of adding type checks in your #hunt method, which won't throw a compiler error (or will have to always throw one). If you always throw it, then developers using your code (and quite possibly yourself) will just auto fill try-catch blocks around every single invocation of #hunt just to handle an error for Human. This adds a lot of "code noise", which just makes things messy.
In short, runtime exceptions are for developer errors like "hunting a human", and there's too many reasons to list for why having this as a static method (let alone main class) is not good from a design standpoint.

Why are interfaces helpful?

I know exactly what are the differences between Interfaces and Abstract classes, but why are Interfaces helpful? look at this :
Now imagine abstractions Point and Circle. How would you achieve that a MovablePoint is both Movable and Point? Only interfaces can give you that, and that's what they are here for.
see HERE
An abstract class is good if you think you will plan on using inheritance since it provides a common base class implementation to
derived classes.
An abstract class is also good if you want to be able to declare non-public members. In an interface, all methods must be public.
If you think you will need to add methods in the future, then an abstract class is a better choice. Because if you add new method
headings to an interface, then all of the classes that already
implement that interface will have to be changed to implement the new
methods. That can be quite a hassle.
Interfaces are a good choice when you think that the API will not change for a while.
Interfaces are also good when you want to have something similar to multiple inheritance, since you can implement multiple interfaces.
SO in your scenario only with interfaces you can specify if a MovablePoint is both Movable and Point.
Yes--in this instance you could have, but try looking at the bigger picture, too. I asked the same question when I first learning OOP and interfaces confused me for a long time.
What if you wanted to add the 'movable' methods to an object that wasn't a subclass of Point, let's say 'MovableJPEG' or some such thing. The end result of the move actions would be the same, but you'd have to rewrite the interface for both classes and different methods to handle moving these features around in classes that interacted with Movable objects.
With an interface you pass a any number of Types related only by having a similar interface to the same method because their implementation details are guaranteed to be the same.
Both interfaces and abstract classes allow a programmer to write modular classes.
The advantage of an interface over an abstract class is that it does not carry any predefined methods or properties with it. An abstract class may have things that you do not want implemented inside of your class.
A second advantage is that a java class can only extend one class, but a large number of interfaces.
Interfaces provide more freedom, where an abstract class can influence the internal design of a class. One advantage of an abstract class is code sharing, which is more difficult with interfaces.
you do not have multiple inheritance in java. so multiple classes cant be inherited in same class but multiple interfaces can be implemented
helps in keeping things organized. Like all the things related to DOG is under one interface, all CATs under CAT and so on.
Runtime polymorphisim : with interface u can have superclass reference variable referring different different sub classes. This helps in keeping code clean, improves scalability ( makes possible all those bridge/proxy/factory etc design patterns which otherwise might not have been there).
Imagine someone using your library wants to introduce something other usable, such as a MovableTirangle. If they let this implement Movable, it can be perfectly used with your library.
For example, the library provides a
void move(Movable m, int horiz, int vert) {
int i;
if (horiz >= 0) {
for (i=0; i < horiz; i++) {
m.moveRight();
}
} else {
for (i=0; i > horiz; i--) {
m.moveLeft();
}
}
if (vert >= 0) {
for (i=0; i < vert; i++) {
m.moveUp();
}
} else {
for (i=0; i > vert; i--) {
m.moveDown();
}
}
}
which can be used with all current and future kinds of Movables.
Until now, this is valid for base classes as well, so that doesn't really count.
But, as Java doesn't support multiple inheritance, a class cannot inherit from more than one base class. But it can implement more than one interface, if this should be needed.
Besides, if you had a functional interface (which you haven't, because you have more than one non-default function in it), you could additionally make use of the new lambda feature of Java. That's another thing which doesn't work with abstract classes.
Let you are trying to give as set of similar property to some unrelated classes. Then you may use interface. For example -
<Bounceable>
/ \
Ball Tire
Here Ball and Tire (of a car) are totally unrelated. But both of them are Bounceable. If you want two unrelated class to have the same property then you can use interface.
There is another important use of interface - giving the flavor of multiple inheritance but with more efficiently than multiple inheritance (where there is a common Deadly Diamond of Death problem.). For example you are expecting a Ball should be both Bouncable and Serializeable. Here Bouncable and Serializeable are totally unrelated of each other. Then you can use interface here. Abstract class need to be extended/inherited and in java multiple inheritance is not possible. So we can provide completely unrelated property to a class by using interface.
Conceptual Difference:
I will not list all the differences between using interfaces or abstract classes or when to use each of them, I think you will find a lot of resources in the web and SO talking only about that, as an example: How should I have explained the difference between an Interface and an Abstract class?
To answer you, Yes, you can use only abstract class in your example and you don't have to use an interface
But, there is a Conceptual Difference, Interfaces are not created to expose public behavior, it's a contract for what a class can do.
While abstract classes are parent of a hierarchy to produce children having core structure and providing default behavior.
Analogy with your example:
Conceptually, Movable must be an Interface because it defines what a class that implements Movable can do (can move up, move down, move...) and not how to do it (Circle dosn't move like Rectangle). While your MovableCircle could be an abstract class because we can define methods like : calculateArea(), getRadius(), calculateCircumference(), ... Which is a default behavior for classes that will inherit from it like MovableWheel.
.
IMO while it's correct when people explain interface as a contract i.e. an obligation to implement method signature, i find that they often forget to mention the use of interface as type for the whole group of objects that implement that same interface, and i believe that to be important piece of the puzzle, understanding the usefulness of interface.
Here is a code example (C#) with Cat and Dog classes that uses both interface and absctract class, which hopefully should higlight differences between them.
Assumption 1: both animals say sounds, but these are different sounds (different methods needed)
Assumption 2: both animals can eat, if they are not full (here one method is needed for both animals)
static void Main(string[] args)
{
IanimalBehavior pluto = new Dog();
IanimalBehavior simba = new Cat();
Program.makeAnimals_say_and_eat(pluto);
Program.makeAnimals_say_and_eat(simba);
Program.makeAnimals_say_and_eat(pluto);
Program.makeAnimals_say_and_eat(simba);
Console.ReadLine();
}
static void makeAnimals_say_and_eat(IanimalBehavior animalObject)
{
Console.WriteLine(animalObject.makeSound());
Console.WriteLine(animalObject.eat());
}
interface IanimalBehavior {
string makeSound();
string eat();
}
class Dog : Animal, IanimalBehavior {
public string makeSound() {
return this.GetType().Name + " says: wuf";
}
}
class Cat : Animal, IanimalBehavior {
public string makeSound()
{
return this.GetType().Name + " says: miauw";
}
}
abstract class Animal {
bool _isFull = false;
public string eat()
{
if (_isFull == false)
{
_isFull = true;
return this.GetType().Name + " is now eating";
}
else
{
return this.GetType().Name + " is now too full to eat!";
}
}
}
Notice that animals are declared as interface types:
IanimalBehavior pluto = new Dog();
This will ensure that the method makeAnimals_say_and_eat() can take a parameter type that targets both types of objects (Cat & Dog), so only one method is needed for all animals which is what we want.
static void makeAnimals_say_and_eat(IanimalBehavior animalObject)
{
Console.WriteLine(animalObject.makeSound());
Console.WriteLine(animalObject.eat());
}
The method calls .makeSound() and .eat() from any object that is passed as parameter. Compiler is happy because it knows that any IanimalBehavior type must include both methods because it says so in the contract:
interface IanimalBehavior {
string makeSound();
string eat();
}
on .makeSound() the return value depends on the class type while .eat() is the same for both classes because eat() is declared in absctract class Animal that all animals inherit from.
the ouput of these instructions:
Program.makeAnimals_say_and_eat(pluto);
Program.makeAnimals_say_and_eat(simba);
Program.makeAnimals_say_and_eat(pluto);
Program.makeAnimals_say_and_eat(simba);
are:
Dog says: wuf
Dog is now eating
Cat says: miauw
Cat is now eating
Dog says: wuf
Dog is now too full to eat!
Cat says: miauw
Cat is now too full to eat!
Interface types also gives you the option of storing different objects of similar nature (same interface implemetation) in a single array which you then can iterate.
IanimalBehavior[] animal_list = { new Dog(), new Cat()};
foreach (IanimalBehavior animal in animal_list)
{
Console.WriteLine(animal.eat());
Console.WriteLine(animal.makeSound());
}

Polymorphism and interfaces - clarification?

(pedantic question)
According to wikipedia there are 3 types of polymorphism :
Ad hoc polymorphism
refer to polymorphic functions which can be applied to arguments of
different types, but which behave differently depending on the type of
the argument to which they are applied
In other words : overloading :
function Add( x, y : Integer ) : Integer;
...
function Add( s, t : String ) : String;
Parametric polymorphism
allows a function or a data type to be written generically, so that it
can handle values identically without depending on their type
In other words : Generics
Example :
class List<T> {
class Node<T> { ...
subtype polymorphism
allows a function to be written to take an object of a certain type T,
but also work correctly if passed an object that belongs to a type S
that is a subtype of T
(the most common usage)
Example :
abstract class Animal {
abstract String talk();
}
class Cat extends Animal {
String talk() {
return "Meow!";
}
}
...
Another Example :
class Animal
{
public virtual void eat()
{
Console.Write("Animal eating");
}
}
class Dog : Animal
{
public override void eat()
{
Console.Write("Dog eating");
}
}
Great .
Now I would like to show you the definition of interface :
Interfaces - An interface defines a contract that can be implemented by
classes and structs. An interface can contain methods, properties,
events, and indexers. An interface does not provide implementations of
the members it defines—it merely specifies the members that must be
supplied by classes or structs that implement the interface.
Great.
Question:
Looking at this pseudo code :
Dog implements IWalk {...}
Cat implements IWalk {...}
Array[IWalk] = [new Dog(),new Cat()]
foreach item in array : item.walk();
Is this polymorphism behaviour (invoking walk() on each different object)?
IMHO it is not. why ? because it doesn't corresponds to any of wiki categories mentioned above.
I believe it is pure principle of coding where I look at an object via different glasses - NOT creating/mutating functionality as the 3 paradigms above mention
Am I right ? is this polymorphic behaviour or not ?
I think you are on the right track. Interfaces are not polymorphic themselves. They formalize polymorphism. They allow you to define polymorphic behavior in a declarative way, instead of implementation. I like to think of Interfaces as the bouncers in the club. They just make sure everyone is following the polymorphic rules.
In your example the actual polymorphic behavior isn't related to the interface itself but the method that is shared. The walk method fits the subtype polymorphism example. The interface itself just contractually obligates the child objects to walk.
UPDATE:
based on comment: just to make it clear - looking at an object via different interfaces it implements - is also polymorphic behaviour ?
The interface itself is just a contract (which you nailed in your question). The polymorphism comes from the methods on the contract. "A polymorphic type is a type whose operations can also be applied to values of some other type, or types" (from wikipedia). The interface (contract) is the agreement that holds the methods (terms) of service or use. So each contract hold the terms that are the polymorphic behavior.
Dog implements IWalk, ITalk, IAnimal
{
//concrete implementation
}
IWalk
{
void walk();
}
ITalk
{
String talk();
}
IAnimal
{
}
I am rusty on java so consider this pseudocode if its not syntactically correct.
IAnimal in this case is just a contract that does not contain polymorphic behavior. IWalk and ITalk promote polymorphism.

In inheritance, what if subclass does not adhere to all super class behavior?

Like there is Mammal class have behavior of walking which all subclasses should adhere to.
But there are few mammals like Dolphin and Bat which does not have this behavior possessed.
How can we implement this?
As per me, all subclasses should adhere to all behavior related to super class.
Any help is appreciated. Thanks!
The Mammal class should only define common characteristics to all mammals, as you said walking is not a common feature.
Behaviour could be added by using interfaces, like in the following example
class abstract Mammal {
abstract void regulateTemperature();
}
interface CanFly {
void land();
void takeOff();
}
class Bat extends Mammal implements CanFly {
}
Sorry if I've made syntax errors, my Java is a bit rusty, but you got the idea, just be as generic as you can in your base class. That said I agree with #dystroy, it's way too difficult to get inheritance right with the animal domain. You might want to try by modelling a lamp, or a shirt, start with something way more simple than this.
Your assertions contradict each other.
Like there is Mammal class have behavior of walking which all subclasses should adhere to.
But there are few mammals like Dolphin and Bat which does not have this behavior possessed.
Either all subclasses have the behavior, or not all have the behavior. You can't have both.
In object-oriented design, it is useful for all subclasses to support the contracts of their superclass, so that an instance of any subclass can be used anywhere that a superclass is referenced. This is known as the Liskov substitution principle.
You have just discovered the fundamental problem with the concept of traditional inheritance and OOP. Classifying objects into strict categories is extremely difficult in even the most trivial examples (interestingly, classification is a big part of IQ tests). When studying the example of the animal kingdom it quickly becomes apparent that grouping times into strict, top down, subdividing, categories doesn't make sense. Combine this idea with programming and trying to reuse functionality and you may end up killing yourself.
Modern OOP avoids using inheritance for code reuse and instead exploits it for polymorphism. Deep inheritance trees are fragile and considered bad practice. Code reuse is instead accomplished through aggregation. Small objects and their behaviors are mixed and matched to create much more complex objects. This behavior is enhanced using concepts like dependency injection and policy based design.
For more info, and practical applications of these concepts, read:
http://en.wikipedia.org/wiki/Composition_over_inheritance
http://en.wikipedia.org/wiki/Aspect-oriented_programming
http://en.wikipedia.org/wiki/Component-based_software_engineering
http://en.wikipedia.org/wiki/Policy-based_design
http://en.wikipedia.org/wiki/Dependency_injection
The Mammal class is not defined correctly in your example since not all mammals can walk. It shouldn't include a walk method. I would opt for a Walking interface instead in that case, with Swimming and Flying interfaces also for the other methods used to move.
If you define Mammal as having a Walk() method, then you're saying that all mammals can walk.
Your implementation for Dolphin might look like this:
public void Walk()
{
throw new TraitLossException();
}
http://www.nescent.org/science/awards_summary.php?id=24
Disclaimer: this answer is not about good design, but about existing practice.
Sometimes, you have a subclass that can't (or just won't) provide all the services the superclass offers. One prominent example would be Iterator.remove(), which can or can not be implemented. When such a situation appears in the Standard libraries, a UnsupportedOperationException is generally thrown. In some cases, like Iterator, it is in a sense even part of the contract that an implementation that does not support the operation should throw the exception.
Simple, use a Walking interface that you can use for animals that walk.
For example:
interface Walking {
public abstract void walk(); // implementing classes must implement this
}
class Cow extends Mammal implements Walking {
public void walk() { ... }
}
class Dolphin extends Mammal {
public void swim() { ... }
}
class Bat extends Mammal {
public void fly() { ... }
}
This is one of those cases where it may makes sense to subclass a non-abstract class.
class Mammal {
...
/** May not walk. This implementation succeeds. */
void walk() {
... do some walking ...
}
}
class WateronlyMammal extends Mammal {
#Override void walk() {
... sit there looking sad ...
}
}
Then create types of animals as new Mammal("Dog") or new WateronlyMammal("Dolphin").
Alternative you may want composition instead of inheritance, which trades verbosity for simpler components.
interface Walker {
/** May not walk. */
void walk();
}
final class Mammal {
public Mammal(String speciesName, Walker walk) {
...
}
...
}
Creating as new Mammal("Dog", competentWalker()) or new Mammal("Dolphin", notSoGoodWalker()).
May even add convenience constructors:
public Mammal(String speciesName) {
this(speciesName, competentWalker(), poorFlyer());
}
(Note we've got some confusion here with type of species and a particular animal being. Also worth noting if you take every animal that ever existed, there are no species boundaries.)

What is the main difference between Inheritance and Polymorphism?

I was presented with this question in an end of module open book exam today and found myself lost. I was reading Head first Javaand both definitions seemed to be exactly the same. I was just wondering what the MAIN difference was for my own piece of mind. I know there are a number of similar questions to this but, none I have seen which provide a definitive answer.
Inheritance is when a 'class' derives from an existing 'class'. So if you have a Person class, then you have a Student class that extends Person, Student inherits all the things that Person has. There are some details around the access modifiers you put on the fields/methods in Person, but that's the basic idea. For example, if you have a private field on Person, Student won't see it because its private, and private fields are not visible to subclasses.
Polymorphism deals with how the program decides which methods it should use, depending on what type of thing it has. If you have a Person, which has a read method, and you have a Student which extends Person, which has its own implementation of read, which method gets called is determined for you by the runtime, depending if you have a Person or a Student. It gets a bit tricky, but if you do something like
Person p = new Student();
p.read();
the read method on Student gets called. Thats the polymorphism in action. You can do that assignment because a Student is a Person, but the runtime is smart enough to know that the actual type of p is Student.
Note that details differ among languages. You can do inheritance in javascript for example, but its completely different than the way it works in Java.
Inheritance refers to using the structure and behavior of a super class in a subclass.
Polymorphism refers to changing the behavior of a super class in the subclass.
Polymorphism: The ability to treat objects of different types in a similar manner. Example: Giraffe and Crocodile are both Animals, and animals can Move. If you have an instance of an Animal then you can call Move without knowing or caring what type of animal it is.
Inheritance: This is one way of achieving both Polymorphism and code reuse at the same time.
Other forms of polymorphism:
There are other way of achieving polymorphism, such as interfaces, which provide only polymorphism but no code reuse (sometimes the code is quite different, such as Move for a Snake would be quite different from Move for a Dog, in which case an Interface would be the better polymorphic choice in this case.
In other dynamic languages polymorphism can be achieved with Duck Typing, which is the classes don't even need to share the same base class or interface, they just need a method with the same name. Or even more dynamic like Javascript, you don't even need classes at all, just an object with the same method name can be used polymorphically.
The main difference is polymorphism is a specific result of inheritance. Polymorphism is where the method to be invoked is determined at runtime based on the type of the object. This is a situation that results when you have one class inheriting from another and overriding a particular method. However, in a normal inheritance tree, you don't have to override any methods and therefore not all method calls have to be polymorphic. Does that make sense? It's a similar problem to all Ford vehicles are automobiles, but not all automobiles are Fords (although not quite....).
Additionally, polymorphism deals with method invocation whereas inheritance also describes data members, etc.
In Java, the two are closely related. This is because Java uses a technique for method invocation called "dynamic dispatch". If I have
public class A {
public void draw() { ... }
public void spin() { ... }
}
public class B extends A {
public void draw() { ... }
public void bad() { ... }
}
...
A testObject = new B();
testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A
Then we see that B inherits spin from A. However, when we try to manipulate the object as if it were a type A, we still get B's behavior for draw. The draw behavior is polymorphic.
In some languages, polymorphism and inheritance aren't quite as closely related. In C++, for example, functions not declared virtual are inherited, but won't be dispatched dynamically, so you won't get that polymorphic behavior even when you use inheritance.
In javascript, every function call is dynamically dispatched and you have weak typing. This means you could have a bunch of unrelated objects, each with their own draw, have a function iterate over them and call the function, and each would behave just fine. You'd have your own polymorphic draw without needing inheritance.
Polymorphism:
Suppose you work for a company that sells pens. So you make a very nice class called "Pen" that handles everything that you need to know about a pen. You write all sorts of classes for billing, shipping, creating invoices, all using the Pen class. A day boss comes and says, "Great news! The company is growing and we are selling Books & CD's now!" Not great news because now you have to change every class that uses Pen to also use Book & CD. But what if you had originally created an interface called "SellableProduct", and Pen implemented this interface. Then you could have written all your shipping, invoicing, etc classes to use that interface instead of Pen. Now all you would have to do is create a new class called Book & CompactDisc which implements the SellableProduct interface. Because of polymorphism, all of the other classes could continue to work without change! Make Sense?
So, it means using Inheritance which is one of the way to achieve polymorphism.
Polymorhism can be possible in a class / interface but Inheritance always between 2 OR more classes / interfaces. Inheritance always conform "is-a" relationship whereas it is not always with Polymorphism (which can conform both "is-a" / "has-a" relationship.
Inheritance is more a static thing (one class extends another) while polymorphism is a dynamic/ runtime thing (an object behaves according to its dynamic/ runtime type not to its static/ declaration type).
E.g.
// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();
-> Though the static/ declaration type of a is A, the actual dynamic/ runtime type is B and thus a.foo() will execute foo as defined in B not in A.
Polymorphism is an approach to expressing common behavior between types of objects that have similar traits. It also allows for variations of those traits to be created through overriding. Inheritance is a way to achieve polymorphism through an object hierarchy where objects express relationships and abstract behaviors. It isn't the only way to achieve polymorphism though. Prototype is another way to express polymorphism that is different from inheritance. JavaScript is an example of a language that uses prototype. I'd imagine there are other ways too.
Inheritance is a concept related to code reuse. For example if I have a parent class say Animal and it contains certain attributes and methods (for this example say makeNoise() and sleep()) and I create two child classes called Dog and Cat. Since both dogs and cats go to sleep in the same fashion( I would assume) there is no need to add more functionality to the sleep() method in the Dog and Cat subclasses provided by the parent class Animal. However, a Dog barks and a Cat meows so although the Animal class might have a method for making a noise, a dog and a cat make different noises relative to each other and other animals. Thus, there is a need to redefine that behavior for their specific types. Thus the definition of polymorphism. Hope this helps.
Oracle documentation quoted the difference precisely.
inheritance: A class inherits fields and methods from all its superclasses, whether direct or indirect. A subclass can override methods that it inherits, or it can hide fields or methods that it inherits. (Note that hiding fields is generally bad programming practice.)
polymorphism: polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.
polymorphism is not applicable for fields.
Related post:
Polymorphism vs Overriding vs Overloading
Polymorphism is achieved by Inheritance in Java.
├── Animal
└── (instances)
├── Cat
├── Hamster
├── Lion
└── Moose
├── interface-for-diet
│ ├── Carnivore
│ └── Herbivore
├── interface-for-habitat
│ ├── Pet
│ └── Wild
public class Animal {
void breath() {
};
}
public interface Carnivore {
void loveMeat();
}
public interface Herbivore {
void loveGreens();
}
public interface Pet {
void liveInside();
}
public interface Wild {
void liveOutside();
}
public class Hamster extends Animal implements Herbivore, Pet {
#Override
public void liveInside() {
System.out.println("I live in a cage and my neighbor is a Gerbil");
}
#Override
public void loveGreens() {
System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
}
}
public class Cat extends Animal implements Carnivore, Pet {
#Override
public void liveInside() {
System.out.println("I live in a cage and my neighbr is a Gerbil");
}
#Override
public void loveMeat() {
System.out.println("I eat Tuna, Chicken, and More");
}
}
public class Moose extends Animal implements Herbivore, Wild {
#Override
public void liveOutside() {
System.out.println("I live in the forest");
}
#Override
public void loveGreens() {
System.out.println("I eat grass");
}
}
public class Lion extends Animal implements Carnivore, Wild {
#Override
public void liveOutside() {
System.out.println("I live in the forest");
}
#Override
public void loveMeat() {
System.out.println("I eat Moose");
}
}
Hamster class inherits structure from Animal, Herbivore and Pet to exhibit Polymorphic behaviorism of a domestic pet.
Cat class inherits structure from Animal, Carnivore and Pet to also exhibit Polymorphic behaviorism of a domestic pet.
Polymorphism is an effect of inheritance. It can only happen in classes that extend one another. It allows you to call methods of a class without knowing the exact type of the class. Also, polymorphism does happen at run time.
For example, Java polymorphism example:
Inheritance lets derived classes share interfaces and code of their base classes. It happens at compile time.
For example, All Classes in the Java Platform are Descendants of Object (image courtesy Oracle):
To learn more about Java inheritance and Java polymorphism
If you use JAVA it's as simple as this:
Polymorphism is using inherited methods but "Overriding" them to do something different (or the same if you call super so wouldn't technically be polymorphic).
Correct me if I'm wrong.
The main purpose of polymorphism : To create reference variable to super class and holding the subclass object => an object can perform multiple behaviours.
In inheritance, subclass inherit the properties of super class.
inheritance is kind of polymorphism, Exactly in fact inheritance is the dynamic polymorphism. So, when you remove inheritance you can not override anymore.
With Inheritance the implementation is defined in the superclass -- so the behavior is inherited.
class Animal
{
double location;
void move(double newLocation)
{
location = newLocation;
}
}
class Dog extends Animal;
With Polymorphism the implementation is defined in the subclass -- so only the interface is inherited.
interface Animal
{
void move(double newLocation);
}
class Dog implements Animal
{
double location;
void move(double newLocation)
{
location = newLocation;
}
}
Inheritance leads to polymorphism, and as such both cannot be compared together like would you compare Car and its AC.
If the question is Define Inheritance and Polymorphism in simple terms, then the definitions as picked from Java docs are:
Inheritance : Object-oriented programming allows classes to inherit commonly used state and behaviour from other classes.
Polymorphism : Subclasses of a class can define their own unique behaviours and yet share some of the same functionality of the parent class.
Inheritance is when class A inherits all nonstatic protected/public methods/fields from all its parents till Object.

Categories

Resources