Spaces:
Running
Running
File size: 6,074 Bytes
5ecac4f |
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 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
Let's also examine a situation where a METHOD is OVERRIDDEN in a subclass.
In the class "Lorry", the method getCapacity has been IMPLEMENTED AGAIN:
class Truck {
private int capacity;
public Truck(int capacity) {
this.capacity = capacity;
}
public int getCapacity() {
return this.capacity;
}
}
class Lorry extends Truck {
private int trailerCapacity;
public Lorry(int capacity, int trailerCapacity) {
super(capacity);
this.trailerCapacity = trailerCapacity;
}
// HERE
@Override
public int getCapacity() {
return super.getCapacity() + trailerCapacity;
}
}
Let's create a new object of type "Lorry", and save the reference to a "Truck"-type variable.
The type of the variable defines the operations that can be used:
thus, we can only call methods defined in the "Truck" class.
So let's call the "getCapacity" method, which is defined in the "Truck" class and overridden in the "Lorry" class.
public class LorryTest {
public static void main(String[] args) {
//INITIALISE 'Lorry' object as a 'Truck' / superclass
Truck vehicle = new Lorry(10, 20);
System.out.println("Capacity: " + vehicle.getCapacity());
}
}
The program outputs
Capacity: 30
From this example, we notice that the method call is directed to the implementation given in the Lorry class, even though the type of the variable is Truck.
As a general rule,
- The VARIABLE TYPE DETERMINES the AVAILABLE OPERATIONS / METHODS
- The OBJECT TYPE determines the IMPLEMENTATIONS used by the METHODS
This is called dynamic binding: Java always looks for the LATEST IMPLEMENTATION of each METHOD.
https://docs [dot] google [dot] com/presentation/d/e/2PACX-1vTpe_7VNECaErEVyCbdD2Ud_CcEaS7sDoG7YD5ic--v34mX0QCzEZRQ-q-ENqkjTI6wiGT-Kh0rHNPl/embed?start=false&loop=false&slide=id.p
==========================================
Note that dynamic binding works in the same way also with internal calls of an object.
Let's look at a situation where the class 'DetectiveNovel' inherits from the class 'Book'.
In the "DetectiveNovel" class, the 'getTitle' method is overridden, but not the toString method.
class Book{
public String getTitle(){
return "book - ";
}
public String getPublisher(){
return "publisher";
}
public String toString(){
return getTitle() + getPublisher();
}
}
class DetectiveNovel extends Book {
@Override
public String getTitle() {
return "detective novel - ";
}
}
When the "toString" method is called for a "DetectiveNovel"-type object,
it always uses the "DetectiveNovel" class implementation for the "getTitle" method:
public class DetectiveNovelTest {
public static void main(String[] args) {
Book book = new DetectiveNovel();
System.out.println(book.toString());
}
}
// 'Book' toString()
// IMPLEMENTs getTitle() + getPublisher()
// ie 'DetectiveNovel'/OVERRIDDEN getTitle() + 'Book'/ORIGINAL getPublisher()
The program outputs:
detective novel - publisher
==========================================
Determining the Type of an Object
As the TYPE of an OBJECT DETERMINES the outcome of a METHOD CALL in some situations,
we need to be able to determine the type.
This is done, for instance, with the operator 'instanceof'.
The operator returns the value true, if the given object is of the given class type, i.e.
A instanceof B
obj1 instanceof Class1
variable1 instanceof Class1
returns the value true if A's type is B.
An example clarifies the situation:
public static void main(String[] args) {
Person ollie = new Student("Oliver", "12345", 123);
System.out.println(ollie instanceof Student);
System.out.println(ollie instanceof Person);
System.out.println(ollie instanceof Object);
System.out.println(ollie instanceof Teacher);
}
The Program outputs:
true
true
true
false
So, a "Student" type is both a "Student", "Person" and "Object".
In fact, the statement
A instanceof Object
is true for all Java objects, as "Object" is the superclass of all classes.
If there is a need TO DETERMINE the "ACTUAL" TYPE of an OBJECT and the type of the superclass is not sufficient,
we can use the method "getClass":
public static void main(String[] args) {
Person oliver = new Student("Oliver", "12345", 123);
System.out.println("Oliver is a Person: " + (oliver instanceof Person));
System.out.println("Oliveris a Person: " + (oliver.getClass() == Person.class));
System.out.println("Oliver is a Student: " + (oliver instanceof Student));
System.out.println("Oliver is a Student: " + (oliver.getClass() == Student.class));
}
Ohjelma tulostaa:
Oliver is a Person: true // 'Student' object type is a subclass of 'Person'
Oliver is a Person: false // 'Student' object type was not initialised as a 'Person' class
Oliver is a Student: true // 'Student' object type
Oliver is a Student: true // 'Student' object type was initialised as a 'Student' class
====================
A typical example is the "equals" method,
where it is determined whether an object is of the same type as the object being compared
- see an example by generating the "equals" method in Eclipse!
Let's consider an example of a method that receives a list of "Person"-class type objects
and prints information about each object,
whether it is a "Person", "Student" or "Teacher" object:
// VARIABLE TYPE = 'Person'
// OBJECT TYPE => depends on HOW OBJECTS WERE INITIALISED
public static void whatType(ArrayList<Person> people) {
for (Person person : people) {
if (person.getClass() == Person.class) {
System.out.println("This is a person!");
}
else if (person.getClass() == Student.class) {
System.out.println("This is a student!");
}
else if (person.getClass() == Teacher.class) {
System.out.println("This is a teacher!");
}
}
}
|