For example: Foo ab=new Dog();
Saving object of another type class to reference of another class!
For example: Foo ab=new Dog();
Saving object of another type class to reference of another class!
It's not always necessary to do something like Foo foo = new Bar()
but it's often recommendable to refer to the interface and not the implementation.
This way you can change your implementation without needing to change other code.
For example if you're doing something with Lists and you use ArrayLists you might do:
ArrayList<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
However you might not care what kind of list it is so you're probably better off with
List<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
Now it doesn't matter what kind of List you've got and maybe you find that you'll get better performance with a LinkedList and you can just use that instead of changing any other code.
I would say that polymorphism is most important when receiving objects by other callers though.
Yes if Foo is an interface then this approach gives you more control on your code. You achieve Polymorphism
, Plug-ability
, Maintainability
and Loose coupling
characteristics of java programming language.
Let's say if you are supposed to connect to oracle from your application and written the code like this
OracleDrive driver= new OracleDriver()
driver.connect();
it will solve your problem. But will make your code tightly coupled with OracleDriver. Your application won't compile at all if you remove Oracle related jar from your classpath. And if someone ask you make your app connect to different DBs based on their configuration then you end up with multiple if
s based on your application supported DBs. which is bad practice as per programming standards.
If you all DB drives implements an interface Driver
then you can load driver based on configuration without tightly coupling your code to any specific driver class like this
Driver driver = properties.get(db.driver.class)
driver.connect()
Now you see that you need to change you application to connect to MySql you just need to set that class in your configuration file.
Hope you got my point!
It's more useful with method parameters.
class Animal {
public boolean hasHair = true;
public void speak() {}
}
class Dog extends Animal {
public void speak() {
System.out.println("Woof!");
}
}
class Person {
public void shave(Animal a) {
a.hasHair = false;
a.speak();
}
}
class Main {
public static void main(String[] args) {
Person joe = new Person();
Dog fido = new Dog();
joe.shave(fido);
}
}
In this case a Person can shave any Animal, but we pass it a Dog.
Animal fido = new Dog();
would be less useful, because we know fido is a dog, but consider this:
Animal pet;
if(joe.prefersCats)
pet = new Cat();
else
pet = new Dog();
Simple answer, You cannot do that.
More Complicated Answer, You would be able to do that only if 'Dog' is type of 'Foo'. When will we say Dog is type of 'Foo' is if Dog implements Foo (If an interface) or extends Foo (If another Class or Abstract Class)
Now, coming to advantages of Coding to Interfaces (Technical name of your question) is
1) Java's Polymorphism is based on this (Polymorphism makes runtime change in behaviour possible, Please google polymorphism in java for more information) 2) You are making interfaces independent of implementations by this approach.
hope this answered your question.
This type of declaration is only possible
Foo ab=new Dog();
if Dog class extends class Foo or Foo is an interface which is implemented by Dog class as
class Dog extends Foo { .... }
or
class Dog implements Foo { ... } //Here Foo is an interface
I think so there is no use if you initialize class objects with inherited interface or inherited class as all the base class functions, properties will be available in your derived class object. This type of declaration will come handy if you are initializing multiple objects having same base class with different derived classes.
For Example,
public class MyObject
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class MyFile extends MyObject
{
private String extension;
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
}
public class MyFolder extends MyObject
{
}
If you are initializing
MyObject file = new MyFile();
This is really of no use but it will be useful when we want to initialize
List<MyObject> listOfFilesFolders = new ArrayList<MyObject>();
listOfFilesFolders.add(new MyFile());
listOfFilesFolders.add(new MyFolder());
This 'listOfFilesFolders' can be private variable of another class which keeps list of files/folders present.
Or we want to have function as
private void SomeFunction(MyObject obj)
{
}
which can take all the objects which are derived from base class and perform operation according to base class properties or functions.
See one of my old answers here:
What is the advantage of using interfaces
It's an anecdote about an anecdote that one of my professors once told us.
Long story short, when you get into more complex systems, the reason that you would want this becomes more clear. The ability to separate specification (interface/abstract class and its contract) from implementation (concrete class) is a powerful tool that makes it very easy to write new implementations without having to change code elsewhere in your application. You use the specification in your code, e.g. the specification:
public interface Animal { ... }
Your implementation:
public class Dog implements Animal { ... }
Then in code, you use the specification whenever possible:
Animal a = new Dog();
a.eat(); // All animals eat, so eat() is on the Animal interface
Unless you absolutely need to use the implementation itself:
Dog d = new Dog();
d.bark(); // Other animals don't bark, so we need to have the Dog here
This makes your code cleaner. For example, say I have a method feedAndGroom
. If I didn't have an interface, I would need to create a new method for each animal I want to support:
public static void feedAndGroom(Cat c) { ... }
public static void feedAndGroom(Dog d) { ... }
public static void feedAndGroom(Turtle t) { ... }
Each code block might even look exactly the same, depending on the situation. Even worse, what happens when someone discovers a new animal? We'd have to add a new method each time, which would result in a huge number of methods. The solution to all this duplication is to create an interface around the functionality, then have a single method:
public static void feedAndGroom(Animal a) { ... }
This will take anything that implements the Animal
interface. All these method calls are legal:
feedAndGroom(new Cat());
feedAndGroom(new Dog());
feedAndGroom(new Turtle());
However, these method calls are legal too:
feedAndGroom(new Hyena());
feedAndGroom(new Lion());
feedAndGroom(new Panther());
We may not want to try and feed and groom these animals, at least not wild ones, so we can add a new interface called DomesticatedAnimal
that extends Animal
:
public interface `DomesticatedAnimal` extends `Animal` { ... }
And change our method to:
public static void feedAndGroom(DomesticatedAnimal da) { ... }
Then instead of implementing Animal
, the Dog
, Cat
, and Turtle
classes will implement DomesticatedAnimal
. For example:
public class Dog implements DomesticatedAnimal { ... }
This means that Dog
is both a DomesticatedAnimal
because it directly implements it, and an Animal
by inheritance since DomesticatedAnimal
extends Animal
. The other animals, Hyena
, Lion
, and Panther
, just implement the Animal
interface. This means that our new method won't take just any Animal
like our original one, but instead restricts it down to a specific kind of Animal
object. Meanwhile, any methods written to use the original Animal
interface would still work for all the objects involved.
You can always substitute a reference to a subclass in place of a base class.
In other words, you can always use something more specific in place of something more general—so if you have got a line of code that asks for a Canine, you can send it a reference to a Dog. So this line of code:
Foo ab=new Dog();
means that you are instantiating a new Dog
object, and then creating a
Foo
reference called ab
and pointing it at that object.