- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInterfaceMethods.java
More file actions
Latest commit
149 lines (126 loc) · 5.27 KB
/
Copy pathInterfaceMethods.java
File metadata and controls
149 lines (126 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
packagePhase2_MethodsArraysStrings.Methods;
/**
* Interface Methods - default, static, private (Java 8 / 9)
* ---------------------------------------------------------
* Before Java 8, every method declared in an interface was implicitly PUBLIC
* ABSTRACT - no body allowed. To evolve an interface (e.g. add a new method),
* you had to break every existing implementor. Java 8 fixed this with
* `default` methods, and Java 9 finished the story with `private` methods.
* <p>
*
* The Four Method Flavours Allowed in an Interface (since Java 9)
* ---------------------------------------------------------------
* <p>
*
* 1. ABSTRACT - no body, must be implemented by every concrete class.
* `void doStuff();`
* <p>
*
* 2. DEFAULT - has a body, inherited by implementors unless overridden.
* `default void greet() { ... }`
* <p>
*
* 3. STATIC - utility belonging to the interface itself.
* `static Comparator<...> byLength() { ... }`
* <p>
*
* 4. PRIVATE - helper for the interface's own default/static methods.
* `private boolean isValid(String s) { ... }`
* (Java 9+)
* <p>
*
* Why `default` Was Added
* -----------------------
* Interfaces could not evolve without breaking implementors. Adding
* `default forEach(Consumer)` to java.lang.Iterable in Java 8 was the
* motivating example - every existing collection class got it for free.
* <p>
*
* Why `private` Was Added (Java 9)
* --------------------------------
* To avoid duplicating helper code between default/static methods of the same
* interface. Without `private`, you would have to expose the helper or copy it.
* <p>
*
* Multiple Inheritance and the "Diamond" Problem
* ----------------------------------------------
* A class may implement multiple interfaces. If two of them provide CONFLICTING
* default methods with the same signature, the compiler forces you to override
* the method in your class to disambiguate (you can call
* `Interface.super.method()` to pick one).
* <p>
*
* Modifier Quick Recap
* --------------------
* - Abstract methods : implicitly public abstract.
* - Default / static methods : may be public (default) - no modifier needed.
* - Private methods : private only; cannot be public/protected.
* - Fields in interfaces : implicitly public static final (constants).
*/
publicclassInterfaceMethods {
// ============ A simple interface using all four method flavours ============
interfaceGreeter {
/** Implementors must provide this. */
StringgetName();
/** Java 8 default - the standard greeting; can be overridden. */
defaultStringgreet() {
// Calls a private helper to keep this method tidy.
return"Hello, " + capitalize(getName()) + "!";
}
/** Java 8 default - a louder greeting that reuses greet(). */
defaultStringshout() {
returngreet().toUpperCase();
}
/** Java 8 static - utility tied to the interface, not to instances. */
staticGreeteranonymous() {
return () -> "stranger";
}
/** Java 9 private - helper used by greet(); not part of the public API. */
privateStringcapitalize(Strings) {
if (s == null || s.isEmpty()) returns;
returnCharacter.toUpperCase(s.charAt(0)) + s.substring(1);
}
}
// ============ An implementation that uses the defaults ============
staticclassCustomerimplementsGreeter {
privatefinalStringname;
Customer(Stringname) { this.name = name; }
@OverridepublicStringgetName() { returnname; }
// Inherits greet() and shout() from the interface.
}
// ============ An implementation that overrides a default ============
staticclassRobotimplementsGreeter {
@OverridepublicStringgetName() { return"unit-9"; }
@OverridepublicStringgreet() {
return"BEEP BOOP. I am " + getName() + ".";
}
}
// ============ Diamond conflict - two interfaces with the same default ============
interfaceEnglish { defaultStringhello() { return"Hello"; } }
interfaceFrench { defaultStringhello() { return"Bonjour"; } }
staticclassPolyglotimplementsEnglish, French {
// Required to disambiguate - compile error if omitted.
@OverridepublicStringhello() {
returnEnglish.super.hello() + " / " + French.super.hello();
}
}
publicstaticvoidmain(String[] args) {
Greeterg1 = newCustomer("deepak");
System.out.println(g1.greet()); // uses inherited default
System.out.println(g1.shout()); // default that calls another default
Greeterg2 = newRobot();
System.out.println(g2.greet()); // overridden version
// Static method on the interface
Greeterg3 = Greeter.anonymous();
System.out.println(g3.greet());
// Diamond resolution
Polyglotp = newPolyglot();
System.out.println(p.hello());
// OUTPUT
// Hello, Deepak!
// HELLO, DEEPAK!
// BEEP BOOP. I am unit-9.
// Hello, Stranger!
// Hello / Bonjour
}
}