Java 8: Polymorphism, Abstract & Interface
easy⏱ 5 mincoursejava
Abstract class vs Interface
Abstract class: single inheritance, can have fields, constructors, and any access modifier. Use when subclasses share state and partial implementation (Template Method pattern). Interface: multiple inheritance, no instance fields (only public static final constants), default + static + private methods since Java 8/9. Use for capability contracts (Comparable, Runnable, AutoCloseable).
// Abstract — shared state + template method
abstract class Processor {
protected final String name;
Processor(String name) { this.name = name; }
public final void run() { setup(); process(); teardown(); }
protected abstract void process();
protected void setup() {}
protected void teardown() {}
}
Default methods (Java 8)
interface List<E> { default void sort(Comparator<E> c) {...} } lets interfaces ship a default implementation without breaking existing implementers. This is how Iterable.forEach, Collection.stream, and List.sort were retrofitted. Conflict resolution: if two parent interfaces have the same default method, the implementer must override it (Interface.super.method() to pick one).
interface Greeter {
default String greet(String name) { return "Hello, " + name; }
}
class Impl implements Greeter {}
// new Impl().greet("world") -> "Hello, world" without writing a body
Private interface methods (Java 9)
Before Java 9, shared logic between default methods had to be duplicated or moved to a package-private helper. Java 9 added private methods on interfaces — usable from default methods to share implementation without exposing it.
interface Logger {
default void info(String m) { log("INFO", m); }
default void error(String m) { log("ERROR", m); }
private void log(String level, String m) { System.out.println(level + " " + m); }
}
Build a design advisor
Write advise(req) where req has flags { sharedState, multipleInheritance, constructorLogic, publicConstants, templateMethod }. Return 'abstract-class', 'interface', or 'both' with a short rationale. Test with 4 realistic scenarios and log each recommendation.
Prefer interfaces for public APIs
Exposing an abstract class as the public type forces every consumer into your class hierarchy. Interfaces leave consumers free to implement in any way, compose with other interfaces, and swap implementations. Use abstract classes as an internal implementation aid (often a `Skeletal` class backing an interface, e.g. `AbstractList` behind `List`).
Quiz: Diamond problem
Two interfaces A and B both have default void f(). A class C implements A, B — what happens? Compile error. Java forces C to override f() and pick explicitly (A.super.f() or B.super.f()) — explicit disambiguation, no silent choice.