"When should I use an interface instead of an abstract class?" appears as a design question, an MCQ, and a compilation puzzle. The old shortcut that an interface contains only abstract methods is no longer true. Java 8 added default and static methods, and that change creates the diamond-conflict question students often miss.
The useful distinction is shared state versus a capability contract, not simply methods with bodies versus methods without bodies.
The two Java building blocks
An abstract class is a partial base class. It can hold instance fields, define constructors, provide concrete methods, and leave selected methods abstract for subclasses to implement. A class uses extends to inherit from it, and Java permits only one direct class superclass.
An interface describes a contract that implementing types promise to satisfy. A class uses implements, and it can implement several interfaces. That supports multiple inheritance of type, even though Java does not support extending multiple classes.
For example, Vehicle might be an abstract class if every vehicle shares an identity field and common movement code. Chargeable might be an interface because unrelated classes can all promise a charge() capability without sharing object state.
Interface vs abstract class: point-by-point comparison
Question | Abstract class | Interface |
|---|---|---|
Inheritance | A class can extend one class | A class can implement many interfaces |
Instance state | Allowed | Not allowed |
Fields | Instance, static, mutable, or final | Implicitly |
Constructors | Allowed | Not allowed |
Method bodies | Concrete and abstract methods | Abstract, default, static, and private helper methods |
Member access | Any valid class access modifier | Contract methods are public; helpers may be private |
Best semantic fit | Shared identity, state, and partial implementation | A capability that potentially unrelated types can provide |
An abstract class expresses a strong "is-a" relationship with reusable implementation and possibly shared state. An interface usually expresses "can-do" behaviour. That is a design guide rather than a compiler rule, but it produces clearer models.
The single-inheritance limit is decisive when a class already extends another base. It can still implement more interfaces, but it cannot add a second superclass.
What Java 8 and Java 9 changed in interfaces
Before Java 8, interface instance methods were abstract, so "interfaces have no method bodies" was a usable rule. Java 8 introduced default methods, which have bodies and are inherited by implementing classes. It also introduced static interface methods.
Java 9 added private interface methods. They let several default or static methods share an implementation detail without exposing that helper as part of the public contract.
An interface can therefore ship behaviour, but it still cannot hold per-object instance state. Its fields are constants. This is the modern correction to the old MCQ rule.
Default methods help evolve an interface. A library can add a method with a default implementation without immediately forcing every existing implementation to add code. The trade-off is that two inherited defaults can collide.
The default-method diamond conflict
Suppose two interfaces define the same default method:
interface A {
default void hello() {
System.out.println("A");
}
}
interface B {
default void hello() {
System.out.println("B");
}
}
class C implements A, B {
}C does not compile. A call to new C().hello() would be ambiguous because neither inherited default is more specific. The compiler rejects the class outright with class C inherits unrelated defaults for hello() from types A and B. Java requires C to override the method:
class C implements A, B {
@Override
public void hello() {
A.super.hello();
}
}Now new C().hello() prints A. Replacing the call with B.super.hello() would print B. The override can also provide completely new behaviour instead of choosing either inherited body.

Trace the compiler's decision in order. First, C inherits a candidate hello() from A. Second, it inherits a candidate with the same signature from B. Neither interface is a child of the other, so there is no more-specific winner. The explicit override removes the ambiguity.
One rule outranks this whole contest. If a class inherits a concrete method from its superclass and a default method with the same signature from an interface, the superclass method wins and no override is needed. Defaults only compete with other defaults.
How to choose in a real design
Choose an abstract class when related types share identity, state, and a common partial implementation. A base Employee class might own an id, initialise it in a constructor, and implement a shared printProfile() method while leaving calculatePay() abstract.
Choose an interface when types share only a capability, or when multiple inheritance of type matters. Comparable, Runnable, and a domain-specific Exportable describe abilities without demanding one shared base object.
An interface with one abstract method is a functional interface, even if it also has default or static methods. That single abstract method supplies the target shape for a lambda expression.
Sometimes both structures belong in the same design. An abstract base can hold common state, while one or more interfaces describe optional capabilities. OOP for CS Teaching Exams: Classes, Inheritance and Polymorphism Explained gives the language-neutral foundation these Java rules build on.
Java interface and abstract class traps
Check these statements carefully in MCQs and compilation questions:
Interface fields are implicitly
public static final. They must be initialised and cannot be reassigned.An abstract class may contain zero abstract methods. Marking the class abstract can simply prevent direct instantiation.
Neither an interface nor an abstract class can be instantiated directly.
A concrete class must implement every inherited abstract method. If it does not, the class itself must be abstract.
Default methods are inherited unless a class method or a conflict rule overrides them.
Static interface methods belong to the interface and are called with the interface name. They are not inherited as instance methods.
An interface has no constructor because it has no instance state to initialise.
Pay attention to Java version wording. "An interface cannot have a method body" is false for current Java. A narrower statement about an ordinary abstract interface method may still be true.
How exams and interviews test the difference
Exams sample the comparison table: which type can have a constructor, which supports multiple inheritance of type, and what access or field rules apply. Output and compilation questions often use the diamond conflict and ask whether C must override the default.
Interviews add design context. A strong answer states the main distinction, then connects it to the requirement: shared mutable state suggests an abstract class; a reusable capability across unrelated types suggests an interface.
Four solved questions on interfaces and abstract classes
Work each one before reading the answer. Every snippet below was compiled and run on Java 17, and the answers quote what the compiler actually says.
Question 1. What does new Impl().tag() return?
interface Greet {
default String tag() {
return "interface";
}
}
abstract class Base {
public String tag() {
return "abstract class";
}
}
class Impl extends Base implements Greet {
}A. interface
B. abstract class
C. nothing, the class does not compile because tag() is ambiguous
D. nothing, tag() stays abstract in Impl
Answer: B, "abstract class". This is the class-wins rule, not the diamond rule. Impl inherits a concrete tag() from Base and a default tag() from Greet, and the superclass method silently takes precedence. No override is required and no ambiguity error is raised.
Question 2. Which member is legal inside a Java 17 interface?
A. an instance field that stores per-object state
B. a constructor
C. a private method shared by two default methods
D. a protected abstract method
Answer: C. Private interface methods arrived in Java 9 precisely so that defaults can share a helper without publishing it. Interface members are public or private and never protected, so D fails with modifier protected not allowed here. Interfaces have no constructors and no instance fields, which rules out A and B.
Question 3. Does this compile?
interface Chargeable {
int MAX_LEVEL = 100;
void charge();
}
class Phone implements Chargeable {
public void charge() {
MAX_LEVEL = 90;
}
}Answer: no. MAX_LEVEL is implicitly public static final, so the assignment fails with cannot assign a value to final variable MAX_LEVEL. Phone may read the constant anywhere, but an interface field can never carry per-object mutable state.
Question 4. Config declares no abstract method. Which statement is true?
abstract class Config {
void load() {
System.out.println("loaded");
}
}A. Config does not compile, because an abstract class needs at least one abstract method
B. Config compiles, and new Config() is still illegal
C. Config compiles, and new Config() is legal because nothing is left abstract
D. load() becomes implicitly abstract
Answer: B. The class compiles cleanly, and new Config() is rejected with Config is abstract; cannot be instantiated. Marking a fully implemented class abstract is a deliberate way to force callers through a subclass.
The short version and next step
An abstract class gives related subclasses shared state and partial implementation under single class inheritance. An interface defines a capability and supports multiple inheritance of type. Default methods can provide behaviour, but two unrelated defaults with the same signature force the implementing class to resolve the conflict.
KnowledgeGate's question bank carries about 200 object-oriented programming questions for practising these distinctions. Drill the Java rules in Complete Java, then use Coding & DSA to continue into inheritance, lambdas, collections, and interview problems.




