Realization
Interface implementation
Overview
Realization represents the relationship between an interface and the class that implements it. The implementing class "realizes" the contract defined by the interface by providing concrete implementations of all abstract methods.
This relationship is fundamental to polymorphism and the Dependency Inversion Principle.
Key Concepts
Interface-implementation relationship
Class provides concrete behavior for interface methods
Represented by dashed line with hollow arrow in UML
Enables polymorphism
Supports programming to interfaces
Code Example
1// Interface defining the contract
2public interface Notifier {
3 void send(String message, String recipient);
4 boolean isAvailable();
5}
6
7// Realization: EmailNotifier realizes Notifier
8public class EmailNotifier implements Notifier {
9 private String smtpServer;
10
11 public EmailNotifier(String smtpServer) {
12 this.smtpServer = smtpServer;
13 }
14
15 @Override
16 public void send(String message, String recipient) {
17 System.out.println("Sending email to " + recipient + ": " + message);
18 // Email-specific implementation
19 }
20
21 @Override
22 public boolean isAvailable() {
23 return smtpServer != null && !smtpServer.isEmpty();
24 }
25}
26
27// Realization: SMSNotifier realizes Notifier
28public class SMSNotifier implements Notifier {
29 private String apiKey;
30
31 public SMSNotifier(String apiKey) {
32 this.apiKey = apiKey;
33 }
34
35 @Override
36 public void send(String message, String recipient) {
37 System.out.println("Sending SMS to " + recipient + ": " + message);
38 // SMS-specific implementation
39 }
40
41 @Override
42 public boolean isAvailable() {
43 return apiKey != null && !apiKey.isEmpty();
44 }
45}
46
47// Realization: PushNotifier realizes Notifier
48public class PushNotifier implements Notifier {
49 @Override
50 public void send(String message, String recipient) {
51 System.out.println("Sending push notification to " + recipient);
52 }
53
54 @Override
55 public boolean isAvailable() {
56 return true;
57 }
58}
59
60// Client works with interface
61public class NotificationService {
62 private List<Notifier> notifiers;
63
64 public NotificationService() {
65 this.notifiers = new ArrayList<>();
66 }
67
68 public void addNotifier(Notifier notifier) {
69 notifiers.add(notifier);
70 }
71
72 public void notifyAll(String message, String recipient) {
73 for (Notifier notifier : notifiers) {
74 if (notifier.isAvailable()) {
75 notifier.send(message, recipient);
76 }
77 }
78 }
79}
80
81// Usage
82public class Main {
83 public static void main(String[] args) {
84 NotificationService service = new NotificationService();
85
86 // All realizations of Notifier interface
87 service.addNotifier(new EmailNotifier("smtp.example.com"));
88 service.addNotifier(new SMSNotifier("api-key-123"));
89 service.addNotifier(new PushNotifier());
90
91 service.notifyAll("Hello!", "user@example.com");
92 }
93}EmailNotifier, SMSNotifier, and PushNotifier all realize the Notifier interface, providing different implementations.
Real-World Example
- List interface realized by ArrayList, LinkedList, Vector
- Comparable interface realized by String, Integer, custom classes
- Runnable interface realized by Thread classes
- PaymentProcessor interface realized by Stripe, PayPal, Square
Best Practices
- 1.
Program to interfaces, not implementations
- 2.
Use meaningful interface names (Notifier, PaymentProcessor)
- 3.
Keep interfaces focused (Interface Segregation Principle)
- 4.
Use realization to enable dependency injection
- 5.
Document the contract clearly in the interface
💡 Interview Tips
Explain it's interface-implementation relationship
Know UML notation (dashed line, hollow arrow)
Discuss how it enables polymorphism
Connect to Dependency Inversion Principle
Give examples from Java standard library