Abstract Class vs Interface in Java: Key Differences and Usage
abstract class in Java when you want to share common code among related classes and provide some method implementations. Use an interface when you want to define a contract for unrelated classes to implement, focusing only on method signatures without code sharing.Quick Comparison
This table summarizes the main differences between abstract class and interface in Java.
| Factor | Abstract Class | Interface |
|---|---|---|
| Purpose | Share common code and define base behavior | Define a contract with method signatures |
| Method Implementation | Can have both abstract and concrete methods | Before Java 8: only abstract methods; Java 8+: default and static methods allowed |
| Multiple Inheritance | Not allowed (only single inheritance) | Allowed (a class can implement multiple interfaces) |
| Fields | Can have instance variables with any access modifier | Only static final constants |
| Constructor | Can have constructors | Cannot have constructors |
| Use Case | When classes are closely related | When unrelated classes need to follow the same contract |
Key Differences
An abstract class in Java is like a partially built blueprint. It can have both methods with code and methods without code (abstract methods). This allows you to share common behavior among related classes while forcing subclasses to implement specific methods. It can also have instance variables and constructors.
On the other hand, an interface is a pure contract that specifies what methods a class must have, without dictating how they work. Before Java 8, interfaces could only declare abstract methods, but now they can also have default and static methods with implementations. Interfaces cannot have instance variables or constructors.
Another big difference is inheritance: a class can extend only one abstract class but can implement many interfaces. This makes interfaces very flexible for defining capabilities that many unrelated classes can share.
Code Comparison
abstract class Animal { String name; Animal(String name) { this.name = name; } void eat() { System.out.println(name + " is eating."); } abstract void sound(); } class Dog extends Animal { Dog(String name) { super(name); } @Override void sound() { System.out.println(name + " says: Woof!"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog("Buddy"); dog.eat(); dog.sound(); } }
Interface Equivalent
interface Animal { void eat(); void sound(); } class Dog implements Animal { String name; Dog(String name) { this.name = name; } @Override public void eat() { System.out.println(name + " is eating."); } @Override public void sound() { System.out.println(name + " says: Woof!"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog("Buddy"); dog.eat(); dog.sound(); } }
When to Use Which
Choose an abstract class when:
- You have closely related classes that share common code or state.
- You want to provide some default behavior and force subclasses to implement others.
- You need to define non-static or non-final fields.
Choose an interface when:
- You want to define a contract for unrelated classes to implement.
- You need to support multiple inheritance of type.
- You want to specify capabilities or behaviors without enforcing code sharing.
In short, use abstract classes for code reuse in a class family, and interfaces for flexible, multiple-type contracts.