-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInterfaceMethods.java
More file actions
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
package Phase2_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).
*/
public class InterfaceMethods {
// ============ A simple interface using all four method flavours ============
interface Greeter {
/** Implementors must provide this. */
String getName();
/** Java 8 default - the standard greeting; can be overridden. */
default String greet() {
// Calls a private helper to keep this method tidy.
return "Hello, " + capitalize(getName()) + "!";
}
/** Java 8 default - a louder greeting that reuses greet(). */
default String shout() {
return greet().toUpperCase();
}
/** Java 8 static - utility tied to the interface, not to instances. */
static Greeter anonymous() {
return () -> "stranger";
}
/** Java 9 private - helper used by greet(); not part of the public API. */
private String capitalize(String s) {
if (s == null || s.isEmpty()) return s;
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
}
// ============ An implementation that uses the defaults ============
static class Customer implements Greeter {
private final String name;
Customer(String name) { this.name = name; }
@Override public String getName() { return name; }
// Inherits greet() and shout() from the interface.
}
// ============ An implementation that overrides a default ============
static class Robot implements Greeter {
@Override public String getName() { return "unit-9"; }
@Override public String greet() {
return "BEEP BOOP. I am " + getName() + ".";
}
}
// ============ Diamond conflict - two interfaces with the same default ============
interface English { default String hello() { return "Hello"; } }
interface French { default String hello() { return "Bonjour"; } }
static class Polyglot implements English, French {
// Required to disambiguate - compile error if omitted.
@Override public String hello() {
return English.super.hello() + " / " + French.super.hello();
}
}
public static void main(String[] args) {
Greeter g1 = new Customer("deepak");
System.out.println(g1.greet()); // uses inherited default
System.out.println(g1.shout()); // default that calls another default
Greeter g2 = new Robot();
System.out.println(g2.greet()); // overridden version
// Static method on the interface
Greeter g3 = Greeter.anonymous();
System.out.println(g3.greet());
// Diamond resolution
Polyglot p = new Polyglot();
System.out.println(p.hello());
// OUTPUT
// Hello, Deepak!
// HELLO, DEEPAK!
// BEEP BOOP. I am unit-9.
// Hello, Stranger!
// Hello / Bonjour
}
}