Abstract Classes & Interfaces — Contracts & Capabilities
Abstract Class ও Interface — চুক্তি ও ক্ষমতা
1. When a Class Is Too Incomplete to Exist
Sometimes a type represents an idea, not a concrete thing. "Shape" is an idea — what does it even
mean to new Shape()? You need a circle, a square, something real. Java lets you
declare such an idea as an abstract class: it can hold fields and concrete methods, but
also abstract methods with no body — forcing subclasses to fill them in. The class itself cannot
be instantiated.
Even purer than abstract class is the interface — a pure contract of what a type can do,
usually without any implementation at all. Modern Java interfaces can also include default
and static methods, which keep them evolvable without breaking implementers.
2. abstract class — Partial Implementation
abstract class Shape {
String name;
Shape(String name) { this.name = name; }
// Abstract: no body — subclasses must implement
abstract double area();
// Concrete method shared by all shapes
void describe() { System.out.println(name + " has area " + area()); }
}
class Circle extends Shape {
double r;
Circle(double r) { super("Circle"); this.r = r; }
@Override double area() { return Math.PI * r * r; }
}
class Main {
public static void main(String[] args) {
// new Shape("x"); // ❌ compile error — cannot instantiate abstract
new Circle(3).describe();
}
}
3. interface — A Pure Contract
An interface describes what a type can do, not how. A class implements one or more
interfaces and must supply a body for every abstract method. Since Java 8, interfaces can also contain
default and static methods — implementations that ship with the contract
itself.
interface Payable {
double amount(); // implicitly public & abstract
default String receipt() { // default implementation
return "Amount due: BDT " + amount();
}
static Payable fixed(double v) { // static factory on the interface
return () -> v; // lambda implements amount()
}
}
class Invoice implements Payable {
double total;
Invoice(double total) { this.total = total; }
@Override public double amount() { return total; }
}
class Main {
public static void main(String[] args) {
Payable a = new Invoice(1500);
Payable b = Payable.fixed(750);
System.out.println(a.receipt());
System.out.println(b.receipt());
}
}
Collection interface could
gain methods like forEach without breaking every existing implementation. They are how the
JDK evolves safely.
4. Multiple Interface Inheritance
A Java class extends only one class but implements any number of interfaces. This is how Java gets most of the benefit of multiple inheritance while avoiding the diamond problem: conflicting default methods must be resolved explicitly.
interface Swimmer { default void go() { System.out.println("Swimming"); } }
interface Flyer { default void go() { System.out.println("Flying"); } }
class Duck implements Swimmer, Flyer {
// Conflict — compiler demands explicit choice
@Override public void go() {
Swimmer.super.go();
Flyer.super.go();
}
}
class Main {
public static void main(String[] args) { new Duck().go(); }
}
5. Abstract Class vs Interface — Which to Choose
Use abstract class when…
- You need to share state (fields) across subclasses.
- Subclasses share a non-trivial partial implementation.
- You want protected helpers visible only to descendants.
- The hierarchy is clearly is-a.
Use interface when…
- You want to describe a capability (Comparable, Iterable, Closeable…).
- Unrelated classes should conform to the same contract.
- You need multiple inheritance of type.
- You want to stay flexible for lambdas (SAM interfaces).
6. Vocabulary (শব্দভাণ্ডার)
| Term | Meaning | বাংলায় |
|---|---|---|
abstract class | Class with at least one abstract method; cannot be instantiated. | অন্তত একটি abstract method-যুক্ত class; instantiate করা যায় না। |
abstract method | A method declaration without a body. | Body-হীন method ঘোষণা। |
interface | Pure contract; multiple inheritance of type. | বিশুদ্ধ চুক্তি; একাধিক inheritance সম্ভব। |
implements | Declares a class follows an interface. | Class ঘোষণা করে — এটি একটি interface মানছে। |
default method | Interface method with a body since Java 8. | Java 8+ থেকে interface-এ body-যুক্ত method। |
| SAM interface | Single-Abstract-Method — usable as a lambda target. | একটিই abstract method — lambda দিয়ে implement করা যায়। |
7. Practice Problems
-
Declare an interface
Greeterwith one methodgreet(). Implement it with a lambda and call it.একটি interfaceGreeterঘোষণা করুন (একটি method:greet())। Lambda দিয়ে implement করে কল করুন।✨ Show Answer
Main.javainterface Greeter { void greet(); } class Main { public static void main(String[] args) { Greeter g = () -> System.out.println("Assalamu alaikum"); g.greet(); } } -
Create an abstract class
Appliancewith fieldwatts, a concretedescribe(), and an abstractuse(). SubclassFanwith a realuse().একটি abstract classApplianceবানান (field: watts, concrete describe(), abstract use())।Fansubclass-এ use() বাস্তবায়ন করুন।✨ Show Answer
Main.javaabstract class Appliance { int watts; Appliance(int w) { watts = w; } abstract void use(); void describe() { System.out.println("Uses " + watts + "W"); } } class Fan extends Appliance { Fan() { super(70); } @Override void use() { System.out.println("Fan spins"); } } class Main { public static void main(String[] args) { Appliance a = new Fan(); a.describe(); a.use(); } } -
In 2 sentences, why did Java 8 add default methods to interfaces?দুই বাক্যে — Java 8 কেন interface-এ default method যোগ করল?
✨ Show Answer
Answer: To evolve existing interfaces (notably
Collection) with new methods likeforEachandstreamwithout forcing every existing implementer to add a body. Default methods ship a sensible implementation in the interface itself, so old code keeps compiling while new features become available.Collection-এর মতো পুরনো interface-এ নতুন method (forEach, stream) যোগ করার জন্য — যাতে পুরনো implementation break না হয়। Default method interface-এই একটি default body দেয়, তাই backward compatibility বজায় থাকে।
-
Define two interfaces
PrintableandSavable, both with a defaultname()returning different strings. Make a class implement both and resolve the conflict explicitly.দুটি interfacePrintableওSavableবানান — দুটোরই defaultname()আলাদা string দেয়। একটি class দুটোই implement করে conflict explicit resolve করুন।✨ Show Answer
Main.javainterface Printable { default String name() { return "Printable"; } } interface Savable { default String name() { return "Savable"; } } class Report implements Printable, Savable { @Override public String name() { return Printable.super.name() + " + " + Savable.super.name(); } } class Main { public static void main(String[] args) { System.out.println(new Report().name()); } } -
Name three standard library interfaces and what capability each expresses.তিনটি standard library interface-এর নাম বলুন এবং প্রত্যেকটি কোন capability প্রকাশ করে।
✨ Show Answer
Answer:
Comparable<T>— "instances of this type have a natural ordering" (used byCollections.sort,TreeSet, etc.).Iterable<T>— "I can be walked with a for-each loop" (backbone of every Collection).AutoCloseable/Closeable— "I hold a resource; try-with-resources will callclose()" (streams, JDBC connections, file channels).
Comparable → natural ordering; Iterable → for-each loop সক্ষমতা; AutoCloseable → try-with-resources-এ auto-close।
Summary — Module 16
An abstract class is a partial type: it can carry fields, constructors, and concrete
methods, but also abstract methods that subclasses must implement — and it cannot be instantiated directly.
An interface is a pure contract; since Java 8 it can include default and
static methods, keeping old libraries evolvable. A class extends one class but implements as
many interfaces as it likes — which is how Java gets most of the benefit of multiple inheritance. Prefer
interfaces for expressing capabilities, and abstract classes when you genuinely need shared state with a
single is-a hierarchy.