Abstract class and Interface usage Is-a relation vs Has-a capability
suggest changeWhen to use abstract classes: To implement the same or different behaviour among multiple related objects
When to use interfaces: to implement a contract by multiple unrelated objects
Abstract classes create “is a” relations while interfaces provide “has a” capability.
This can be seen in the code below:
public class InterfaceAndAbstractClassDemo{
public static void main(String args[]){
Dog dog = new Dog("Jack",16);
Cat cat = new Cat("Joe",20);
System.out.println("Dog:"+dog);
System.out.println("Cat:"+cat);
dog.remember();
dog.protectOwner();
Learn dl = dog;
dl.learn();
cat.remember();
cat.protectOwner();
Climb c = cat;
c.climb();
Man man = new Man("Ravindra",40);
System.out.println(man);
Climb cm = man;
cm.climb();
Think t = man;
t.think();
Learn l = man;
l.learn();
Apply a = man;
a.apply();
}
}
abstract class Animal{
String name;
int lifeExpentency;
public Animal(String name,int lifeExpentency ){
this.name = name;
this.lifeExpentency=lifeExpentency;
}
public abstract void remember();
public abstract void protectOwner();
public String toString(){
return this.getClass().getSimpleName()+":"+name+":"+lifeExpentency;
}
}
class Dog extends Animal implements Learn{
public Dog(String name,int age){
super(name,age);
}
public void remember(){
System.out.println(this.getClass().getSimpleName()+" can remember for 5 minutes");
}
public void protectOwner(){
System.out.println(this.getClass().getSimpleName()+ " will protect owner");
}
public void learn(){
System.out.println(this.getClass().getSimpleName()+ " can learn:");
}
}
class Cat extends Animal implements Climb {
public Cat(String name,int age){
super(name,age);
}
public void remember(){
System.out.println(this.getClass().getSimpleName() + " can remember for 16 hours");
}
public void protectOwner(){
System.out.println(this.getClass().getSimpleName()+ " won't protect owner");
}
public void climb(){
System.out.println(this.getClass().getSimpleName()+ " can climb");
}
}
interface Climb{
void climb();
}
interface Think {
void think();
}
interface Learn {
void learn();
}
interface Apply{
void apply();
}
class Man implements Think,Learn,Apply,Climb{
String name;
int age;
public Man(String name,int age){
this.name = name;
this.age = age;
}
public void think(){
System.out.println("I can think:"+this.getClass().getSimpleName());
}
public void learn(){
System.out.println("I can learn:"+this.getClass().getSimpleName());
}
public void apply(){
System.out.println("I can apply:"+this.getClass().getSimpleName());
}
public void climb(){
System.out.println("I can climb:"+this.getClass().getSimpleName());
}
public String toString(){
return "Man :"+name+":Age:"+age;
}
}
output:
Dog:Dog:Jack:16
Cat:Cat:Joe:20
Dog can remember for 5 minutes
Dog will protect owner
Dog can learn:
Cat can remember for 16 hours
Cat won't protect owner
Cat can climb
Man :Ravindra:Age:40
I can climb:Man
I can think:Man
I can learn:Man
I can apply:Man
Key notes:
Animal
is an abstract class with shared attributes:name
andlifeExpectancy
and abstract methods:remember()
andprotectOwner()
.Dog
andCat
areAnimals
that have implemented theremember()
andprotectOwner()
methods.Cat
canclimb()
butDog
cannot.Dog
canthink()
butCat
cannot. These specific capabilities are added toCat
andDog
by implementation.Man
is not anAnimal
but he canThink
,Learn
,Apply
, andClimb
.Cat
is not aMan
but it canClimb
.Dog
is not aMan
but it canLearn
Man
is neither aCat
nor aDog
but can have some of the capabilities of the latter two without extendingAnimal
,Cat
, orDog
. This is done with Interfaces.- Even though
Animal
is an abstract class, it has a constructor, unlike an interface.
TL;DR:
Unrelated classes can have capabilities through interfaces, but related classes change the behaviour through extension of base classes.
Refer to the Java documentation page to understand which one to use in a specific use case.
Consider using abstract classes if…
- You want to share code among several closely related classes.
- You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
- You want to declare non-static or non-final fields.
Consider using interfaces if…
- You expect that unrelated classes would implement your interface. For example, many unrelated objects can implement the
Serializable
interface. - You want to specify the behaviour of a particular data type but are not concerned about who implements its behaviour.
- You want to take advantage of multiple inheritance of type.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents