Interfaces represent a pure responsibility contract: "Any class implementing this must provide these capabilities, regardless of its inheritance hierarchy."
Vehicle (abstract class with common behavior)
Car extends Vehicle, implements Drivable
ElectricCar extends Vehicle, implements Drivable, Electric
Trailer extends Vehicle, implements Towable
Real-world systems often combine both approaches to create flexible and organized designs.
// Abstract base class - handles common state and partial implementation
public abstract class Vehicle {
protected String model;
protected double position;
// Common implementation shared by all vehicles
public String getModel() {
return model;
}
// Abstract methods that all vehicles must implement
public abstract void start();
public abstract void stop();
}
Step 2: Next, we define interfaces for optional capabilities vehicles might have:
// Interface for vehicles that are electric powered
public interface Electric {
void charge();
int getBatteryLevel();
}
// Interface for vehicles that can tow other vehicles
public interface Towable {
void tow(Vehicle other);
int getTowingCapacity();
}
Step 3: Finally, we create concrete vehicle types that combine the abstract class with selected interfaces:
// Concrete class using both approaches
public class ElectricTruck extends Vehicle
implements Electric, Towable {
private int batteryLevel;
private int towingCapacity;
// Implement required abstract methods from Vehicle
@Override
public void start() {
if (batteryLevel > 10) {
System.out.println("Starting electric motor...");
} else {
System.out.println("Battery too low to start!");
}
}
@Override
public void stop() {
System.out.println("Stopping electric motor...");
}
// Implement Electric interface
@Override
public void charge() {
batteryLevel = 100;
System.out.println("Battery fully charged");
}
@Override
public int getBatteryLevel() {
return batteryLevel;
}
// Implement Towable interface
@Override
public void tow(Vehicle other) {
System.out.println("Towing " + other.getModel());
}
@Override
public int getTowingCapacity() {
return towingCapacity;
}
}
This design leverages the strengths of both approaches:
A set of shapes in a drawing application where every shape must have an area and perimeter calculation, but some shapes might require different additional properties (e.g., a circle has a radius, a rectangle has width and height).
A set of devices (e.g., printers, scanners, projectors) that must implement a connect() method but may have completely different ways of working otherwise.
A hierarchy of vehicles where all vehicles share common attributes like speed and fuel capacity, but different types of vehicles (cars, boats, planes) have specialized behaviors.
A payment system where different payment methods (credit card, PayPal, bank transfer) must implement a processPayment() method but don’t share any default implementation.
A game where different types of characters (warrior, mage, archer) have common characteristics such as health and attack power, but specific attack strategies differ.
Interfaces cannot have constructors. Constructors are used to initialize object state, but interfaces cannot contain instance variables (except constants).
False.
Interfaces cannot have constructors. Constructors are used to initialize object state, but interfaces cannot contain instance variables (except constants).
Abstract classes can contain a mix of abstract methods AND concrete methods with implementations. In fact, this is one of their key advantages over interfaces.
False.
Abstract classes can contain a mix of abstract methods AND concrete methods with implementations. In fact, this is one of their key advantages over interfaces.
This is correct. Java allows a class to implement multiple interfaces simultaneously, which is a way to achieve a form of multiple inheritance for behavior.
False.
This is correct. Java allows a class to implement multiple interfaces simultaneously, which is a way to achieve a form of multiple inheritance for behavior.
You cannot instantiate abstract classes directly. You must create a concrete subclass that implements all abstract methods, then instantiate that subclass.
False.
You cannot instantiate abstract classes directly. You must create a concrete subclass that implements all abstract methods, then instantiate that subclass.