Theory
Three things that must print
BookBridge now prints receipts for issued books, fine payments and new membership cards. Three classes, unrelated by family: a FineReceipt is not a kind of MembershipCard.
Yet the dashboard wants to treat them identically: "everything printable, print yourself at closing time."
Inheritance cannot express this: there is no sensible common parent, and Java allows only one extends anyway. What we need is not a shared ancestor but a shared promise: sign here, and you can print.
Theory
A contract, not a bloodline
A driving licence does not care who your parents are: pass the test, and you may drive. Doctors, students and shopkeepers all hold one.
An interface is that licence for classes: a list of abilities with no implementation attached. Any class from any family can sign it, and signing means one thing: you must actually provide these methods. Family is inherited; contracts are signed. Java lets a class have one family and many contracts.
Theory
Declaration and the implicit rules
interface Printable {
void print();
}
What the compiler silently adds, and exams ask about:
- every method is implicitly public abstract: a signature, no body
- every field is implicitly public static final: a constant, must be initialised
- there are no constructors:
new Printable()is meaningless and illegal
A class signs with implements and must define all the methods, or declare itself abstract:
class FineReceipt implements Printable { ... }
Practical
Two contracts, one class
interface Printable {
void print(); // implicitly public abstract
}
interface Payable {
void collect(int amount);
}
class FineReceipt implements Printable, Payable { // many contracts at once
public void print() { // public is COMPULSORY here
System.out.println("Fine receipt printed");
}
public void collect(int amount) {
System.out.println("Collected Rs " + amount);
}
}
public class BookBridge {
public static void main(String[] args) {
Printable p = new FineReceipt(); // interface reference
p.print();
}
}
Theory
The multiple-inheritance debt, paid
Back in the Java-vs-C++ lesson, a promise was made: Java forbids 2 parent classes but has another route to the idea. This is it.
class FineReceipt implements Printable, Payable takes on both contracts, and interfaces themselves can inherit: interface Printable extends Displayable stacks contract upon contract.
Why is this safe when 2 parent classes were not? Interfaces carry no state and no method bodies, so the C++ diamond problem (which parent's data? whose implementation?) has nothing to collide over.
Quiz
class Card implements Printable declares print() but forgets the public keyword: void print() { ... } What happens?
- Compiles fine; default access is enough within the package
- Compile error: an implementing method cannot have weaker access than public
- Runtime error when print() is first called through the interface
- The compiler silently adds public for you
Show the answer
Compile error: an implementing method cannot have weaker access than public
Interface methods are implicitly public, and an override may never REDUCE visibility, so default access is a step down and javac rejects it: this is the single most common compile error when students first implement interfaces. Option A applies the package rule from a context it does not govern. Option C is too late: Java settles access at compile time. Option D describes what interfaces do to their own declarations, not to your implementing class.
Think first
Interface vs abstract class
Both can hold abstract methods, neither can be instantiated. Before tapping: name 2 differences that decide when you would pick an interface.
Show the answer
1: how many. A class extends at most 1 abstract class but implements many interfaces; if a Card must be both Printable and Payable, interfaces are the only route. 2: what they may contain. An abstract class can have instance fields, constructors and ordinary method bodies for children to inherit; an interface has none of that, only the contract (its fields are public static final constants). Rule of thumb: shared implementation, abstract class; shared capability, interface.
Watch out
The 3 interface traps
new Printable() does not compile: no constructors, nothing to build. An interface variable can only HOLD an implementing object: Printable p = new FineReceipt();
Partial implementation: implement 2 of 3 methods and the class must be declared abstract, or it will not compile.
extends vs implements: class to class is extends, class to interface is implements, interface to interface is extends. Swapping them is an instant compile error.
Theory
This pattern runs the Java world
Interface references give polymorphism across families: the dashboard holds Printable references and calls print() without caring what each object really is, exactly like Person p = new Member() but with no bloodline required. Keep the shape in mind: in Unit 4, making BookBridge's due-date reminder run in the background is literally class Reminder implements Runnable, one more signed contract. Android (BCA305-02) wired every button click the same way.
Summary
Key takeaways
- An interface is a pure contract: method signatures, no bodies, no state, no constructors.
- Methods are implicitly public abstract; fields are implicitly public static final.
- A class implements many interfaces and must define every method as public, or be abstract.
- Interfaces extend interfaces; classes implement interfaces; classes extend one class.
- Interface references (Printable p = new FineReceipt()) give cross-family polymorphism.
- No state and no bodies is why multiple contracts are safe where multiple parents were not.
- Memory hook: one family, many licences.