Skip to content

How should I have explained the difference between an Interface and an Abstract

An interface defines a set of functions that a class must implement. While methods in an interface are abstract by default, Java 8+ allows interfaces to include default and static methods with implementations. A class that implements an interface must still provide implementations for any abstract methods it inherits.

An abstract class, on the other hand, is a class that cannot be instantiated and is used as a base class for one or more derived classes. An abstract class can contain both abstract and concrete methods, and it can provide a default implementation for some of its methods. A derived class can override the abstract methods and the methods with a default implementation as needed.

Here are a few key differences between interfaces and abstract classes:

  1. Method implementations: Interfaces can only contain default or static methods with bodies, whereas abstract classes can contain fully implemented concrete methods.
  2. Multiple inheritance: A class can implement multiple interfaces but can only extend a single abstract class.
  3. Fields and access modifiers: Interface fields are implicitly public static final constants, and methods are implicitly public. Abstract classes can declare instance fields with any access modifier (private, protected, etc.).
  4. Purpose: Interfaces define a contract or capability, whereas abstract classes provide a shared base implementation for closely related classes.
java
// Interface with a default method
interface Flyable {
    void fly();
    default void land() {
        System.out.println("Landing...");
    }
}

// Abstract class with concrete and abstract methods
abstract class Bird {
    protected String name;
    public Bird(String name) { this.name = name; }
    public abstract void chirp();
    public void eat() { System.out.println(name + " is eating."); }
}

// Concrete class implementing interface and extending abstract class
class Sparrow extends Bird implements Flyable {
    public Sparrow(String name) { super(name); }
    @Override
    public void fly() { System.out.println(name + " is flying."); }
    @Override
    public void chirp() { System.out.println(name + " is chirping."); }
}

I hope this helps. Let me know if you have any questions.

Do you find this helpful?

Dual-run preview — compare with live Symfony routes.