☕ Java
Interfaces in Java
Interfaces define a contract: 'if you claim to be X, you must be able to do Y and Z.' They're how Java achieves flexible, loosely coupled design — and since Java 8, they've become even more powerful.
Interface vs Abstract Class — When to Use Which
This comes up in interviews constantly. Here's the practical breakdown:
| Feature | Interface | Abstract Class |
|----------------------|--------------------------------|---------------------------------|
| Methods | abstract by default | can be abstract OR concrete |
| Variables | public static final only | any type (instance vars allowed)|
| Inheritance | implements (multiple allowed) | extends (single only) |
| Constructor | No | Yes |
| Best for | Defining a capability/contract | Sharing common implementation |
Rule of thumb: If you're defining WHAT something can do (capability) → interface. If you're defining a SHARED BASE with some shared code → abstract class.
Real examples:
• Comparable, Runnable, Serializable in Java's own library → all interfaces (capabilities)
• AbstractList, AbstractMap in Collections → abstract classes (shared implementation)
Default Methods (Java 8+) — Backwards-Compatible Evolution
Before Java 8, adding a new method to an interface broke all existing classes that implemented it. Default methods solve this — you can add new methods with a default implementation, and existing classes don't need to change.
This is how Java's Collections API added stream() and forEach() to List without breaking millions of existing codebases.
Java
interface Vehicle {
void start(); // all implementors must provide this
// Default method — implementors get this for free, can override if needed
default void stop() {
System.out.println("Vehicle stopping — applying brakes");
}
default void fuelStatus() {
System.out.println("Fuel level: checking...");
}
// Static method in interface — utility method, called on the interface itself
static int maxSpeedLimit() {
return 120;
}
}
class Car implements Vehicle {
public void start() {
System.out.println("Car engine starting — vroom!");
}
// stop() and fuelStatus() inherited with default implementations
@Override
public void stop() {
System.out.println("Car stopping — applying ABS brakes");
}
}
Car car = new Car();
car.start(); // Car engine starting — vroom!
car.stop(); // Car stopping — applying ABS brakes (overridden)
car.fuelStatus(); // Fuel level: checking... (default)
System.out.println(Vehicle.maxSpeedLimit()); // 120 (static)Related Topics in Object-Oriented Programming
Classes and Objects
OOP's big idea: model your software the same way you think about the real world. A class is a blueprint, an object is the actual thing. Once this clicks, Java starts to feel natural.
Inheritance
Inheritance lets you build new classes on top of existing ones — reusing code instead of rewriting it. If a SavingsAccount IS-A BankAccount, why define all the BankAccount stuff twice? Inherit it.
Polymorphism
Polymorphism means 'many forms'. The same method call can behave differently depending on which object is actually behind it. It's what lets you write flexible, extensible code without rewriting existing logic.
Encapsulation
Encapsulation is about protecting your data. Make fields private, and control access through methods. It's the reason your bank balance can't be changed by just anyone who gets hold of your account object.