File size: 4,869 Bytes
3b7dc42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
It is common that there is a PROPERTY we would like to declare for MULTIPLE CLASSES. 
For example, we could have several classes that have a price. 
However, since a price can be attached to very different classes (for example a car, a banana, an airplane, and a house), 
it would be difficult to come up with a common superclass.


For this, we have INTERFACES. 
The idea of an interface is that it DEFINES a PROPERTY THAT the CLASSES CAN then IMPLEMENT. 
In practice, the interface (which is a sort of CLASS ITSELF) TYPICALLY DEFINES a METHOD or METHODS WITHOUT actual IMPLEMENTATION. 
The classes that implement the interface then implement the method(s) as well.

This enables the grouping of objects based on a single property, 
even if the objects themselves are very different (for example a banana and an airplane). 
This way we can for example calculate the total price of different objects with price by using a simple loop.



========================================



Interfaces in Java
In Java, an interface is defined with the keyword 'interface'. 
Inside the interface, ALL DECLARED MEMBERS are PUBLIC, because the implementing classes need to PROVIDE the MEMBERS TO their CLIENTS.

For example, see the interface 'Priced':
interface Priced {
    int getPrice();
}


Note that getPrice() is a 'method declaration'. 
VISIBILITY MODIFIERS are NOT NEEDED, since ALL the MEMBERS defined in the interface are PUBLIC.

As seen in the example, 'no implementations for the methods are given' in the interface. 
The interface is implemented with keyword 'implements' (different from 'extends', which is used when we extend a class).

class Car implements Priced {
    private String manufacturer;
    private String model;
    private int price;

    public Car(String manufacturer, String model, int price) {
        this.manufacturer = manufacturer;
        this.model = model;
        this.price = price;
    }

    // update method
    @Override
    public int getPrice() {
        return price;
    } 
}
 




As a second example, let's look at class Banana. 
This time the price is fixed at 5. 
This does not make a difference, the interface just defines that the class needs to return an integer from the method getPrice().

class Banana implements Priced {
    double length;
    
    public Banana(double length) {
        this.length = length;
    }

    @Override
    public int getPrice() {
        return 5;
    }
}
 




The implementing classes can have a very different basic idea. 
However, they need to implement the method getPrice() which is defined in the interface.

public class Test {
    public static void main(String[] args) {
        Car car = new Car("Volvo", "345", 1500);
        Banana banana = new Banana(15.25);
        
        System.out.println(car.getPrice());
        System.out.println(banana.getPrice());
    }
}

Program outputs:
1500
5
 
 


========================================



In the newer versions of Java, interface methods can have default implementations. 
This helps for example when you need to make changes in the interface. 
The feature is not discussed in detail in this course, more information can be found e.g. at:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

 

========================================

Let's see a second example, an interface called Measurable which defines methods getWidth and getHeight.

interface Measurable {
    double getWidth();
    double getHeight();
}



Now the implementing classes MUST IMPLEMENT BOTH METHODS:
class Block implements Measurable {
    private String material;
    private double width;
    private double height;
    
    public Block(String material, double width, double height) {
        this.material = material;
        this.width = width;
        this.height = height;
    }


    ////////////////////
    // HERE
    ////////////////////
    @Override
    public double getWidth() {
        return width;
    }

    @Override
    public double getHeight() {
        return height;
    }
    ////////////////////
    
    public String getMaterial() {
        return material;
    }
}






 

A class can implement more than one interface:
class Block implements Measurable, Priced {
    private String material;
    private double width;
    private double height;
    
    public Block(String material, double width, double height) {
        this.material = material;
        this.width = width;
        this.height = height;
    }

    ////////////////////
    // HERE
    ////////////////////
    @Override
    public double getWidth() {
        return width;
    }

    @Override
    public double getHeight() {
        return height;
    }

    @Override
    public int getPrice() {
        return 25;
    }
    ////////////////////
    
    public String getMaterial() {
        return material;
    }
}