The labs on this site need JavaScript to run. The same content is written out below.
Learn › Java › Classes and objects
Interfaces and abstract classes
Neither can be created with new, so how do they differ?
An interface and an abstract class both define a contract that says "these methods must exist", and both leave the actual implementation to the class that implements them. But they differ in whether a class can inherit from several of them at once and in whether they can have state (fields).
Checked against real execution · The 12 combinations were compiled and run on JDK 21 and checked against the results
Concepts in this lab
- Interface
- This is a type that defines the list of methods (the contract) that a class must implement. It cannot have instance variables, and one class can implement several of them. If the calling code depends only on this type, it is easy to change the implementing class or to replace it with a fake implementation for testing.
- Abstract class
- This is a class that is declared abstract, so you cannot create an instance of it directly. It can have both abstract methods with no implementation and ordinary methods with an implementation, and it can also have fields (state) and constructors. It is used to gather the state and common logic that several subclasses share, and a class can extend only one class.
- Default method
- This is a feature, available since Java 8, that lets an interface contain a method with an implementation. It was introduced so that adding a new method to an interface does not break the existing implementing classes. If such methods from several interfaces conflict, the implementing class must override the method itself.
- Abstraction
- This means hiding the complex details of something and showing only the essential features that are needed. In Java, an interface or an abstract class declares only "what can be done", and the implementing class decides how to do it. The code that uses it can rely on the declared features alone, without knowing the implementation.
- Inheritance
- This means defining a new class (the subclass) that receives the fields and methods of an existing class (the superclass). It reuses common code, and the subclass adds or overrides only the parts it needs. A Java class supports single inheritance only, and a change to the superclass affects every subclass, so it is best used only when there is a clear "is-a" relationship.
- Polymorphism
- This is the property that calling the same method through a reference of the same type runs different behavior depending on the kind of the actual object. A variable of a supertype (an interface or a superclass) can hold objects of several subtypes, and which implementation runs is decided at run time (dynamic method lookup). It lets you add a new implementation without changing the calling code.
Try these
- Default settings — A class can implement several interfaces at once.
- Extending two abstract classes — A class can extend only one class, so this does not compile.
- A field and a constructor in an interface — An interface cannot have the state of an object.
- A field and a constructor in an abstract class — It can pass shared state and initialization code down to its subclasses.
- Using new directly — Neither one can be used by itself to create an object.
- Not implementing an abstract method — If a method required by the contract is missing, the compiler rejects the class.
Running with the default settings
- Payable is an interface. It defines only the contract "there must be a method named pay()", and the class that implements it decides how to pay.
- Card implements two interfaces, Payable and Refundable, at once. An interface has no state, so combining several of them causes no field conflict (if the same default method appears in more than one, you must decide it yourself).
- The code compiles. A Card object can be assigned to a variable of type Payable and also to a variable of type Refundable.
Result of this run
- A class can extend only one class (extends), but it can implement several interfaces (implements). To give a class several abilities of the form "can do something", use interfaces.
- How to choose: use an interface to attach the contract "provides this feature" to classes of different kinds, and use an abstract class when closely related classes need to share fields and code. In practice, interfaces are often the default choice.
Code
interface Payable {
void pay(); // abstract method: no body
default String name() { return "default name"; }
}
interface Refundable { void refund(); }
class Card implements Payable, Refundable {
public void pay() { }
public void refund() { }
}
Assumptions of this model
For all 12 combinations, source code with the same structure as the code on the screen was actually compiled and run on JDK 21 on this PC, and the model was checked against the results (whether compilation succeeded and the error messages). Features from later versions, such as private methods and static methods in interfaces and sealed types, are not covered.
Previous lab: Polymorphism and method selection · Next lab: Access modifiers and encapsulation