As stated here
https://standardofnorms.wordpress.com/2012/09/02/4-pillars-of-object-oriented-programming/
and as the correct answer in many job interviews - the general correct answer for the question:
"What are the 4 pillars of OOP?" is:
Abstraction
Encapsulation
Inheritance
Polymorphism
What I fail to understand is how inheritance not contained in polymorphism?
in other words, how can polymorphism be used without the use of inheritance?
The only way I know of using polymorphism is
class A{
virtual void foo(){cout<<"A";}
void bar(){cout<<"A";}
};
class B : public A{
virtual foo(){cout<<"B";}
};
A* ab = new B();
ab->foo();//prints B, using polymorphism
ab->bar();//prints A, using inheritance
A* a = new A();
a->foo();//prints A
a->bar();//prints A, obviously
As I see it, polymorphism brings with it inheritance.
Please explain why it is distinct - or why can't inheritance be discarded as a key pillar of its own. We could use polymorphism or not.
What I fail to understand is how inheritence not contained in
polymorphism?
in other words, how can polymorphism be used without the use of
inheritence?
There are 3 main types of polymorphism, and only one of them requires inheritance to work.
Ad-hoc polymorphism: This is more commonly known as function/method overloading, where multiple functions can share the same name but have different signatures. Whether or not the return type is part of the signature is language dependent.
Parametric polymorphism: in OOP, this is more commonly known as generics, where a function/method can work with multiple concrete types, and return multiple concrete types, providing compile time safety.
Subtype polymorphism: This is the one I think most people think of when they talk about polymorphism. As you know, this is when subtypes provide different implementation of their parent functions/methods.
You can read more about the different types of polymorphism from the wikipedia article here: https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
As I understand the two concepts:
Inheritance
You could use inheritance without using polymorphisim. For example:
class Base {
public:
void foo();
};
class Derived : public Base {
};
int main() {
Derived d;
d.foo();
}
Here we use the common functionality of the base type in all derived types, but at no point do we do anything polymophic (we never look at the derived instance though its base interface).
Polymorphism
Polymorphism as a concept includes more than the standard inheritance based method seen most often. This is actually subtyping which is just one kind of Polymorphism.
Writing a template method is technically a form of polymophism, and function overloading another. As a concept you could argue that many other things are ways to achieve polymophism.
For example:
// This function must be given an object that has a method foo().
template <typename T> bar(T& t) {
t.foo();
}
This is polymorphic behavior without inheritance.
See: https://stackoverflow.com/a/10556406/1230538 for a really good explaination of this given by someone else.
Summary
99% you use inheritance to achieve polymorphism in most modern programming languages, but they are different concepts, and can exist/be used independently of each other.
Polymorphism without inheritance:
class A {
virtual void foo() { cout << "A"; }
};
class B {
virtual void foo() { cout << "B"; }
};
A* a = new A();
A* b = new B();
a->foo(); // prints A
b->foo(); // prints B
Both instances have the same method. So they are polymorphic. However, the method does different things because the objects are different after all.
Related
After reading this post I think I mostly understand LSP and most of the examples, but I can’t say I’m 100% certain from my experience of many examples of inheritance, as it seems that many examples do violate LSP and it seems difficult not to when overriding behaviour.
For instance, consider the following simple demonstration of inheritance, taken from Head First Object Oriented Analysis & Design. Aren't they violating LSP with the Jet child class?
public class Airplane {
private int speed;
public void setSpeed(int speed) {
this.speed = speed;
}
public int getSpeed() {
return speed;
}
}
public class Jet extends Airplane {
private static final int MULTIPLIER=2;
/**
* The subclass can change behaviour of its superclass, as well as call the
* superclass's methods. This is called overriding the superclass's behaviour
*/
public void set setSpeed(int speed) {
super.setSpeed(speed * MULTIPLIER);
}
public void accelerate() {
super.setSpeed(getSpeed() * 2);
}
}
A client using a reference to an instance of base class Airplane might be surprised, after setting the speed, to find it is twice as fast as expected after being passed an instance of a Jet object. Isn't Jet changing the post-conditions for the setSpeed() method and thus violating LSP?
E.g.
void takeAirplane(Airplane airplane) {
airplane.setSpeed(10);
assert airplane.getSpeed()==10;
}
This will clearly fail if takeAirplane is passed a reference to a Jet object.
It seems to me that it will be difficult not to violate LSP when “overriding a superclass’s behaviour”, yet this is one of the main/desirable features of inheritance!
Can someone explain or help clarify this? Am I missing something?
According to Wikipedia
[The Liskov substitution principle] states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).
In the case of the Jet, it's speed being twice as fast is a violation of the LSP - it fails the postcondition that setSpeed(getSpeed(x))==x
The Liskov Substitution Principle says that it's ok to modify the behaviour of in a derived class, provided the correctness of the program does not change. It imposes restrictions on the changes you make in the derived classes.
It is certainly not for good OOP design - as the need for common behavior of all instances of a derived class is quite valid conceptually. Moreover, it would make for so much cleaner code if one could just say Data.parse(file), have the common parse() code in the base class and let overriding do its magic than having to implement mostly similar code in all data subtypes and be careful to call DataSybtype.parse(file) - ugly ugly ugly
So there must be a reason - like Performance ?
As a bonus - are there OOP languages that do allow this ?
Java-specific arguments are welcome as that's what I am used to - but I believe the answer is language agnostic.
EDIT : one could ideally :
<T> void method(Iface<? extends T> ifaceImpl){
T.staticMeth(); // here the right override would be called
}
This will also fail due to erasure (in java at least) - if erasure is at work one needs (would need) to actually pass the class :
<T, K extends T> void method(Iface<K> ifaceImpl, Class<K> cls){
cls.staticMeth(); // compile error
}
Does it make sense ? Are there languages doing this already ? Is there a workaround apart from reflection ?
Speaking to C++
class Foo {
public:
static void staticFn(int i);
virtual void virtFn(int i);
};
The virtual function is a member function - that is, it is called with a this pointer from which to look up the vtable and find the correct function to call.
The static function, explicitly, does not operate on a member, so there is no this object from which to look up the vtable.
When you invoke a static member function as above, you are explicitly providing a fixed, static, function pointer.
foo->virtFn(1);
expands out to something vaguely like
foo->_vtable[0](foo, 1);
while
foo->staticFn(1);
expands to a simple function call
Foo##staticFn(1);
The whole point of "static" is that it is object-independent. Thus it would be impossible to virtualize.
Say I have a class A
class A
{
Z source;
}
Now, the context tells me that 'Z' can be an instance of different classes (say, B and C) which doesn't share any common class in their inheritance tree.
I guess the naive approach is to make 'Z' an Interface class, and make classes B and C implement it.
But something still doesn't convince me because every time an instance of class A is used, I need to know the type of 'source'. So all finishes in multiple 'ifs' making 'is instanceof' which doesn't sound quite nice. Maybe in the future some other class implements Z, and having hardcoded 'ifs' of this type definitely could break something.
The escence of the problem is that I cannot resolve the issue by adding functions to Z, because the work done in each instance type of Z is different.
I hope someone can give me and advice, maybe about some useful design pattern.
Thanks
Edit: The work 'someone' does in some place when get some instance of A is totally different depending of the class behind the interface Z. That's the problem, the entity that does the 'important job' is not Z, is someone else that wants to know who is Z.
Edit2: Maybe a concrete example would help:
class Picture
{
Artist a;
}
interface Artist
{
}
class Human : Artist { }
class Robot : Artist {}
Now somewhere I have an instance of Picture,
Picture p = getPicture();
// Now is the moment that depending if the type of `p.a` different jobs are done
// it doesn't matter any data or logic inside Human or Robot
The point of using an interface is to hide these different implementations; A should just know the intent or high-level purpose of the method(s).
The work done by each implementation of Z may be different, but the method signature used to invoke that work can be the same. Class A can just call method Z.foo(), and depending on whether the implementation of Z is B or C, different code will be executed.
The only time you need to know the real implementation type is when you need to carry out completely unrelated processing on the two different types, and they don't share an interface. But in that case, why are they being processed by the same class A? Now, there are cases where this may make sense, such as when B and C are classes generated from XML Schemas, and you can't modify them - but generally it indicates that the design can be improved.
Updated now that you've added the Picture example. I think this confirms my point - although the implementation of getPicture() is different, the purpose and the return type are the same. In both cases, the Artist returns a Picture.
If the caller wants to treat Robot-created and Human-created pictures in the same way, then they use the Artist interface. They do not need to distinguish between Human or Robot, because they just want a picture! The details of how the picture is created belong in the subclass, and the caller should not see these details. If the caller cares about precisely how a picture is created, then the caller should paint it, not the Robot or Human, and the design would be quite different.
If your subclasses are performing totally unrelated tasks (and this is not what your Artist example shows!) then you might use a very vague interface such as the standard Java Runnable; in this case, the caller really has no idea what the run() method will do - it just knows how to run things that are Runnable.
Links
The following questions/articles suggest some alternatives to instanceof:
Avoiding instanceof in Java
Alternative to instanceof approach in this case
And the following articles also gives example code, using an example that seems similar to yours:
http://www.javapractices.com/topic/TopicAction.do?Id=31
and the following articles discuss the tradeoffs of instanceof versus other approaches such as the Visitor pattern and Acyclic Visitor:
https://sites.google.com/site/steveyegge2/when-polymorphism-fails
http://butunclebob.com/ArticleS.UncleBob.VisitorVersusInstanceOf
I think you need to post more information, because as it stands what I see is a misunderstanding of OOP principles. If you used a common interface type, then by Liskov substitution principle it shouldn't matter which type source is.
I'm gonna call your A, B, and C classes Alpha, Beta, and Gamma.
Perhaps Alpha can be split into two versions, one which uses Betas and one which uses Gammas. This would avoid the instanceof checks in Alpha, which as you've surmised are indeed a code smell.
abstract class Alpha
{
abstract void useSource();
}
class BetaAlpha extends Alpha
{
Beta source;
void useSource() { source.doSomeBetaThing(); }
}
class GammaAlpha extends Alpha
{
Gamma source;
void useSource() { source.doSomeGammaThing(); }
}
In fact this is extremely common. Consider a more concrete example of a Stream class that can use either Files or Sockets. And for the purpose of the example, File and Socket are not derived from any common base class. In fact they may not even be under our control, so we can't change them.
abstract class Stream
{
abstract void open();
abstract void close();
}
class FileStream extends Stream
{
File file;
void open() { file.open(); }
void close() { file.close(); }
}
class SocketStream extends Stream
{
Socket socket;
void open() { socket.connect(); }
void close() { socket.disconnect(); }
}
I'm a little confused with the two terms, here's what I know:
Polymorphism is the ability of object of different types to be handled by a common interface. While duck typing, is a kind of dynamic typing that allows objects of different types to respond to the same methods.
From what I understand, polymorphism is more about creating an interface that can be shared across different classes. And duck typing is about loose typing that will allow methods to be called as long as it is found on the receiver of the message.
Is this correct? I'm pretty confused on the two, they seem related but I do not know what their relationship is. Thanks a lot in advance!
Polymorphism (in the context of object-oriented programming) means a subclass can override a method of the base class. This means a method of a class can do different things in subclasses. For example: a class Animal can have a method talk() and the subclasses Dog and Cat of Animal can let the method talk() make different sounds.
Duck typing means code will simply accept any object that has a particular method. Let's say we have the following code: animal.quack(). If the given object animal has the method we want to call then we're good (no additional type requirements needed). It does not matter whether animal is actually a Duck or a different animal which also happens to quack. That's why it is called duck typing: if it looks like a duck (e.g., it has a method called quack() then we can act as if that object is a duck).
So are these related? They are simply separate features that a programming language may have. There are programming languages which have polymorphism but that do not have duck typing (such as Java). There are also languages that have polymorphism and duck typing (such as Python).
This is an example for Polymorphism in Python.
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal)
print(animal.name + ': ' + animal.talk())
This is an example for duck Typing in Python.
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
def name(self):
print("ITS A DUCK NO NAME")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")
def in_the_forest(duck):
duck.quack()
duck.feathers()
duck.name()
def game():
for element in [Duck(), Person()]:
in_the_forest(element)
game()
In polymorphism we see subclass (Cat and Dog) inheriting from the parent class (Animal) and overriding the method Talk.
In case of duck typing we don’t create a subclass instead new class is created with method having same name but different function.
Short Answer:
Duck typing is one way of achieving Polymorphism.
Another way is by using static typing.
Long Answer:
There are two different concepts involved here, typing and programming technique.
Duck typing is a type of typing. And typing means when to throw error when an object passed around isn't what is expected. Duck typing is a kind of typing where it throws error when the program is running and the method being called isn't available. Static typing comes with compile time checking, so if the type info doesn't match, it will throw error when you compile the code. And that is typing.
Polymorphism is a programming technique where you allow multiple types of object to fulfill certain responsibilities. You can do that by using a base type to represent all the child class types. You can use duck typing to represent all the different types that have the needed methods. You can use an interface to represent all the types that implement the interface.
There are answers saying polymorphism is inheritance, and that is not correct. Although you can use inheritance to create polymorphic behavior and usually that's what you do, but that's not what polymorphism is about.
For one, you don't need inheritance to have polymorphism as described above.
Secondly, the term "Polymorphism" is more meaningful in the context of the client code that depends on abstraction, and not the implementation code. Just because you have a super class and a few other classes that inherit from it and overriding some methods does not mean it's polymorphism, to create polymorphism you have to write client code in a polymorphic way to consume these classes.
Two type Polymorphism
Method overloading(Compile time Polymorphism ).
Method overriding(Run Time Polymorphism ).
Method overloading :- same function name and different data type is known as Method overloading
Example :
int addTwovalues(int a, int b)
{ return (a+b)}
float addTwovalues(float a, float b)
{ return (a+b)}
Method overriding :- same function name and same data type but different Class
is known as Method overriding.
class a
{
virtual int addtwovalues()
{ // to do }
}
class b:a
{
override int addtwovalues()
{ // to do }
}
a obj=new a();
obj.addtwovalues();
b objb=new a();
objb.addtwovalues(); //run time Polymorphism
Suppose we have the following pseudo code. I am talking about OO languages.
class A{
foo(){...}
}
class B extends A{
foo(){...}
}
class C extends B{
foo(){...}
}
static void f(A a)
{
A a=new A();
a=new B();
a.foo();
}
It's easy for us to recognize that a.foo() is calling function foo overridden in class B. So why it's hard for compilers to get this truth by static analysis? The fundamental question here is why statically determine the type of A is hard for a compiler?
The example you posted is extremely simplistic and does not show anything that requires a virtual method call. With your same classes, examine this function;
void bar(A* a) {
a->foo();
}
There is no way the compiler can tell at compile-time if a is an instance of B, or C, or a plain A. That can only be decided at runtime in the general case.
The compiler can't even know if there will be new classes derived from A at some future point that will be linked with this code.
Just imagine:
A a = createInstanceFromString("B");
Now you're screwed.
On a serious note, your example is way too simplistic. Imagine if a right-hand side of an assignment is a call to a function defined in some other "module" (whatever this means). This means that the compiler has to inspect all execution paths in order to determine the exact type of a return value, but that's prohibitively expensive and sometimes downright impossible.