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 implements keyword.

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.

Parcel, Cab and FoodOrder all realize Trackable. TrackingScreen only knows the interface
Loading diagram...

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.

SmartSpeaker realizes three interfaces, BasicPhone only two
Loading diagram...

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.

Employee classes inherit from Employee. Freelancer and OfficeRent only realize Payable
Loading diagram...

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 sharedFields and method codeMethod signatures (plus optional default methods)
How many per classOne parent classAny number of interfaces
UML lineSolid line, hollow triangleDashed line, hollow triangle
ExampleIntern extends EmployeeFreelancer 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
Collections.sort() works only because ExamRank keeps the Comparable contract
Loading diagram...

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:

Choosing between an interface and an abstract class
Loading diagram...

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 UnsupportedOperationException from several methods. That usually means the class does not really fulfil the contract.
  • Forgetting @Override on 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.