Every wall socket in an Indian home follows the same standard. A phone charger, a mixer grinder and a laptop adapter have nothing in common inside, but each of them has a plug that fits that socket, so each of them works in any house. The socket defines what is expected, and every appliance fulfils it in its own way. In object-oriented design, a class that fulfils a contract like this is said to realize it.
Realization is the relationship between an interface (the contract) and a class that implements it (the fulfilment). In Java you write it with the
implementskeyword.
Real-world analogy: a job posting says "must be able to drive a car and hold a valid licence". A delivery executive, a cab driver and a family chauffeur can all meet that requirement, even though their jobs are very different. The posting cares only that the requirement is met, not who meets it or how.
1. What Is Realization?
An interface lists the methods that must exist. A class that realizes the interface promises to provide every one of them. The compiler checks that promise: if a class says implements Trackable and forgets a method, it does not compile.
- The interface describes what must be done. The class decides how.
- Several unrelated classes can realize the same interface, each in its own way.
- One class can realize several interfaces at once.
- Code that uses the interface does not need to know which class it is talking to.
Realization is about a shared capability, not a shared identity. A parcel, a cab and a food order are very different things, but all three can be tracked.
2. How Realization Looks in UML
Realization is drawn as a dashed line with a hollow triangle pointing at the interface. It looks a lot like inheritance, which uses a solid line with the same triangle. The dashed line is the reminder that the class is keeping a promise, not inheriting code from a parent.
3. A First Example: Tracking Anything
A delivery app has to show live status for parcels, cabs and food orders. These three classes share no parent and no fields. What they share is the ability to answer two questions: what is your tracking ID, and what is happening right now? That is the Trackable contract.
Output
PCL-88120347 | Reached Hyderabad hub
CAB-TS07EX4410 | Driver is 4 min away
FOOD-5521 | Out for delivery
A few things to notice. The interface has no code at all, only method signatures, so every class writes its own version. TrackingScreen.show() accepts a Trackable and never mentions Parcel, Cab or FoodOrder. And adding a new trackable thing tomorrow, say a train ticket, means writing one new class. The screen and the loop stay exactly as they are.
4. One Class, Many Contracts
A Java class can extend only one class, but it can implement as many interfaces as it needs. That makes it natural to split capabilities into small interfaces and let each class pick the ones it supports. A smart speaker can play music, answer questions and ring an alarm. A basic phone can play music and ring an alarm, but here it is not a voice assistant.
Output
Speaker playing: Suprabhatam
Phone playing: Suprabhatam
Weather: Hyderabad, 31 C, clear sky
Speaker alarm set for 6:00 AM
Phone alarm set for 6:00 AM
Each method asks for only the capability it needs. setWakeUp() takes an AlarmClock, so it happily works with both devices. askWeather() takes a VoiceAssistant, so passing the phone is a compile error. The type system stops the mistake before the code ever runs. This idea of small, focused interfaces is also what the Interface Segregation Principle in SOLID asks for.
5. Realization vs Inheritance
Both relationships use a hollow triangle in UML, and both let you treat different classes through one type, so they are easy to confuse. The difference is what is being shared.
Inheritance shares identity and code. A FullTimeEmployee is an Employee: it inherits the name field and the payee() method. Realization shares only a contract. A Freelancer and the office rent are not employees at all, but they still need to be paid every month, so they realize Payable. The two relationships work well together, as this payment run shows.
Output
Paying Meena (full-time): Rs 85000
Paying Rahul (intern): Rs 15000
Paying Arjun (freelancer, 40 h): Rs 48000
Paying Office rent (Madhapur): Rs 120000
Total paid this month: Rs 268000
| Inheritance (extends) | Realization (implements) | |
|---|---|---|
| Models | "is a" identity | "can do" capability |
| What is shared | Fields and method code | Method signatures (plus optional default methods) |
| How many per class | One parent class | Any number of interfaces |
| UML line | Solid line, hollow triangle | Dashed line, hollow triangle |
| Example | Intern extends Employee | Freelancer implements Payable |
6. Realizing Java's Own Interfaces
You realize interfaces from the Java library all the time, often without thinking of it as a design relationship. Comparable is a good example. Collections.sort() does not know how to order your objects, so it relies on a contract: if your class implements Comparable, it will call compareTo() to decide the order.
Output
1. Asha - 92 marks, 38 min
2. Sita - 92 marks, 41 min
3. Kiran - 88 marks, 35 min
4. Farhan - 75 marks, 50 min
The same pattern appears across the JDK. Implement Runnable and a thread can run your code. Implement AutoCloseable and your object works in a try-with-resources block. Implement Iterable and it works in an enhanced for loop. In each case the library depends on the interface and your class realizes it.
7. Default and Static Methods in Java Interfaces
Since Java 8, an interface can also carry a little code. A default method gives every implementing class a ready behaviour that it may override, and a static method is a helper that belongs to the interface itself.
interface Trackable {
String trackingId();
String currentStatus();
default String summary() { // every Trackable gets this for free
return trackingId() + " | " + currentStatus();
}
static boolean isValidId(String id) { // helper on the interface itself
return id != null && id.contains("-");
}
}
Use default methods sparingly. They are great for adding a small convenience without breaking existing classes, but an interface should stay mainly a contract. If you find yourself putting fields and lots of logic into it, an abstract class is probably the better tool.
8. Interface or Abstract Class?
A common design question is whether a shared type should be an interface or an abstract class. This rough guide works well in interviews and in real projects:
9. Common Mistakes
- Building one big interface with many unrelated methods, so that implementing classes are forced to write empty methods they don't need.
- Using an abstract class only to define method signatures. If there is no shared state or code, an interface is lighter and lets the class extend something else.
- Declaring variables and parameters with the concrete class (
Cab cab) when the interface (Trackable item) would do. You lose the flexibility the interface was meant to give. - Implementing an interface "partially" by throwing
UnsupportedOperationExceptionfrom several methods. That usually means the class does not really fulfil the contract. - Forgetting
@Overrideon the implementing methods. It costs nothing and catches typos in method names at compile time.
Summary
- Realization is the "implements a contract" relationship between an interface and a class.
- In UML it is a dashed line with a hollow triangle pointing at the interface.
- Unrelated classes can realize the same interface, and one class can realize many interfaces.
- Code that depends on the interface works with any class that realizes it, so new classes can be added without changing that code.
- Use inheritance for real "is a" relationships with shared code, and realization for shared capabilities.