So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
This is known as inhertiance and not polymorphism. MyClass
is a Parent
and MyClass
is also a Naming
. That being said, inheritance
allows you to achive polymorphism
.
Consider a class other thanMyClass
that also implements Naming
:
class SomeOtherClass implements Naming {
@Override
public void someMethodDefinedInTheInterface() {
}
}
Now consider a method that takes a Naming
argument somewhere in your code base :
public void doSomething(Naming naming) {
naming.someMethodDefinedInTheInterface();
}
The doSomething
method can be passed an instance of any class
that implements Naming
. So both the following calls are valid :
doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2
Observe how you can call doSomething
with different parameters. At runtime, the first call will call someMethodDefinedInTheInterface
from MyClass
and the second call will call someMethodDefinedInTheInterface
from SomeOtherClass
. This is known as runtime-polymorphism
which can be achieved through inheritance.
But I don't get how injection works. The idea is that I would not be using the @Override keyword during injection
That's true in the broader sense. To inject
something into a class, the class should ideally favor composition
over inheritance
. See this answer that does a good job in explaining the reason for favoring composition over inheritance.
To extend the above example from my answer, let's modify the doSomething
method as follows :
public class ClassHasANaming {
private Naming naming;
public ClassHasANaming(Naming naming) {
this.naming = naming;
}
public void doSomething() {
naming.someMethodDefinedInTheInterface();
}
}
Observe how ClassHasANaming
now has-a Naming
dependency that can be injected from the outside world :
ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();
If you use the Factory pattern, you can actually chose which subclass gets instantiated at runtime.
Do you think we could have done what we did above using inheritance
?
public class ClassIsANaming implements Naming {
public void doSomething() {
someMethodDefinedInTheInterface();
}
@Override
public void someMethodDefinedInTheInterface() {
//....
}
}
The answer is No. ClassIsANaming
is bound to a single implementation of the someMethodDefinedInTheInterface
method at compile time itself.
`