HAS-A Relationship Association is a relationship where all objects have their own lifecycle and there is no owner. For example, teacher student Aggregation is a specialized form of association where all objects have their own lifecycle, but there is ownership and child objects can not belong to another parent object. For example, knight sword Composition is a specialized form of aggregation and we can call this as a death relationship. For example, house room Zheng-Liang Lu Java Programming 253 / 294
Example: Lines on 2D Cartesian Coordinate +2: two Point objects contained in a Line object. Zheng-Liang Lu Java Programming 254 / 294
More Examples More geometric objects, say Circle, Triangle, and Polygon. Complex number (a + bi) equipped with + and so on. Book with Authors. Lecturer and Students in the classroom. Zoo with many creatures, say Dog, Cat, and Bird. Channels played on TV. Zheng-Liang Lu Java Programming 255 / 294
More Relationships Between Classes So far, we have seen how to define classes and also create objects. There exist more relationships among classes: inheritance: passing down states and behaviors from parent classes to its child classes interfaces: grouping the methods, which belongs to some classes, as an interface to the outside world packages: grouping related types, providing access protection and name space management Zheng-Liang Lu Java Programming 256 / 294
Inheritance Different kinds of objects often share common properties with each other. For example, human-beings and dogs are two specific types of animals. Yet, each also defines additional features that make themselves more specific. For simplicity, let A be a class defined as follows: 1 class A { 2 int x = 1; 3 void foo() { 4 System.out.println("This is from A."); 5 } 6 } Zheng-Liang Lu Java Programming 257 / 294
Example 1 class B extends A { 2 int y = 2; 3 void hoo() { 4 System.out.println("This is from B."); 5 } 6 } 7 8 public class inheritancedemo { 9 public static void main(string[] args) { 10 A a = new A(); 11 a.foo(); 12 System.out.println("a.x = " + a.x); 13 14 B b = new B(); 15 b.foo(); 16 b.hoo(); 17 System.out.println("b.x = " + b.x); 18 System.out.println("b.y = " + b.y); 19 } 20 } Zheng-Liang Lu Java Programming 258 / 294
First IS-A Relationship OO allows classes to inherit commonly used states and behaviors from other classes. So the classes exist in some hierarchy. A class can be declared as a subclasses of another class, which is called superclass, by using the extends keyword. So we can say that a subclass specializes its superclass. Equivalently, one subclass is a special case of the superclass. Note that a class can extend only one other class. Each superclass has the potential for an unlimited number of subclasses. Zheng-Liang Lu Java Programming 259 / 294
Class Hierarchy 1 1 See Fig. 3-1 in p. 113 of Evans and Flanagan. Zheng-Liang Lu Java Programming 260 / 294
The super Keyword Recall that the keyword this is used to refer to the object itself. You can use the keyword super to refer to members of the superclass. Note that this() and super() are used as the constructor of the current class and that of its superclass, respectively. Make sure all the constructor are invoked in the first line in the constructors. Zheng-Liang Lu Java Programming 261 / 294
Constructor Chaining If a subclass constructor invokes a constructor of its superclass, you might think that there will be a whole chain of constructors called, all the way back to the constructor of the class Object, the topmost class in Java. So every class is an immediate or a distant subclass of Object. Recall that the method finalize() and tostring() are inherited from Object. tostring(): return a string which can be any information stored in the class. Zheng-Liang Lu Java Programming 262 / 294
1 class A { 2 private int x; 3 Example 4 A() { 5 System.out.println("A..."); 6 } 7 8 A(int x) { 9 this(); 10 this.x = x; 11 } 12 } 13 14 class B extends A { 15 B() { 16 super(10); 17 System.out.println("B..."); 18 } 19 20 public String tostring() { return new String(super.x); } 21 } 22 Zheng-Liang Lu Java Programming 263 / 294
23 24 25 public class constructorchainingdemo { 26 public static void main(string[] args) { 27 B b = new B(); 28 System.out.println(b); 29 } 30 } The println() method takes an object as inputs, and invokes tostring() method implicitly. Zheng-Liang Lu Java Programming 264 / 294
Field Hiding If one field whose name is identical to the field inherited from the superclass, then the newly field hides that of the superclass. In other words, the shadowed field of the superclass cannot be referenced by the field name. Instead, the field must be accessed through the key word super. Zheng-Liang Lu Java Programming 265 / 294
Example 1 class A { 2 int x = 1; 3 } 4 5 class B extends A { 6 int x = 2; 7 8 int getxfroma() { 9 return super.x; 10 } 11 } 12 13 class FieldHidingDemo { 14 public static void main(string[] args) { 15 B b = new b(); 16 System.out.println(b.x); // output 2 17 System.out.println(b.getXfromA()); // output 1 18 } 19 } Zheng-Liang Lu Java Programming 266 / 294
Method Overriding The subclass is allowed to change the behavior inherited from its superclass if needed. As a subclass defines an instance method using the method name, return type, and parameters all identical to the method of its superclass, this method overrides the one of the superclass. 2 Compared to overridden methods, method overloading occurs only in the same class. Similarly if your method overrides one of its superclass s methods, you can invoke the overridden method through the use of the keyword super. 2 The static methods do not follow this rule. Zheng-Liang Lu Java Programming 267 / 294
When there are multiple implementations of the method in the inheritance hierarchy, the one in the most derived class (the furthest down the hierarchy) always overrides the others, even if we refer to the object through a reference variable of the superclass type. 3 3 An overridden method in Java acts like a virtual function in C++. See the virtual method table. Zheng-Liang Lu Java Programming 268 / 294
Example Zheng-Liang Lu Java Programming 269 / 294
Binding Association of method definition to the method call is known as binding. The binding which can be resolved at compile time by compiler is known as static binding or early binding. They are the static, private and final methods. Compiler knows that all such methods cannot be overridden and will always be accessed by object of local class. When compiler is not able to resolve the binding at compile time, such binding is known as dynamic binding or late binding. For example, method overriding. Zheng-Liang Lu Java Programming 270 / 294
Polymorphism In OO design, the word polymorphism, which literally means many forms, refers to the ability of reference variables to take different forms. The Liskov Substitution Principle states that one variable associated with the declared type can be assigned an instance from any direct or indirect subclass of that type. 4 Let U be a a subtype of T. Then T variables may refer to U objects. 4 It is a semantic rather than merely syntactic relation because it intends to guarantee semantic interoperability of types in a hierarchy, object types in particular. See https://en.wikipedia.org/wiki/liskov_substitution_principle. Zheng-Liang Lu Java Programming 271 / 294
Casting Upcasting (widening conversion) is to cast the U object to the T variable. 1 T t = new U(); Downcasting (narrow conversion) is to cast the T variable to a U variable. 1 U u = (U) t; // t is T variable reference to a U object. Upcasting is always allowed, but downcasting is allowed only when the T variable refer to a real U object. This involves type compatibility by JVM during program execution. Zheng-Liang Lu Java Programming 272 / 294
instanceof Operator The operator instanceof allows us to test whether or not a reference variable is compatible to the object. If not compatible, then JVM will throw an exception ClassCastException. 5 5 We will see the exceptions later. Zheng-Liang Lu Java Programming 273 / 294
1 class T {} 2 class U extends T {} 3 Example 4 public class InstanceofDemo { 5 public static void main(string[] args) { 6 T t1 = new T(); 7 8 System.out.println(t1 instanceof U); // output false 9 System.out.println(t1 instanceof T); // output true 10 11 T t2 = new U(); // upcasting 12 13 System.out.println(t2 instanceof U); // output true 14 System.out.println(t2 instanceof T); // output true 15 16 U u = (U) t2; // downcasting; this is ok. 17 18 u = (U) new T(); // pass the compilation; fail during execution! 19 } 20 } Zheng-Liang Lu Java Programming 274 / 294
Exercise Zheng-Liang Lu Java Programming 275 / 294
1 public class AnimalFamilyDemo { 2 public static void main(string[] args) { 3 Dog d = new Dog(); 4 d.sleep(); 5 d.eat(); 6 d.watchdoor(); 7 8 Animal a = d; // upcasting 9 a.sleep(); 10 a.eat(); 11 a.watchdoor(); // oops, invisible! 12 a.chaselittlething(); // oops, invisible! 13 14 d = (Dog) a; // downcasting 15 d.watchdoor(); // works! 16 } 17 } Zheng-Liang Lu Java Programming 276 / 294
Field Hiding with Polymorphism You can refer to hidden fields simply by casting an object to a variable of the appropriate superclass. 1 class T { 2 int x = 1; 3 } 4 5 class U extends T { 6 int x = 2; 7 } 8 9 public class FieldHidingDemo { 10 public static void main(string[] args) { 11 U u = new U(); 12 System.out.println(u.x); // output 2 13 T t = u; 14 System.out.println(t.x); // output 1 15 } 16 } Zheng-Liang Lu Java Programming 277 / 294
Method Overriding with Polymorphism However, you cannot invoke overridden methods by upcasting. JVM calls the appropriate method for the object. Method lookup starts from the bottom of the class hierarchy to the top. Always looking for the most specific method body. These methods are referred to as virtual methods. This mechanism preserves the behaviors of the objects and the superclass type variables play the role of placeholders. Zheng-Liang Lu Java Programming 278 / 294
Example Imagine that we have a zoo with some animals. 1 class Animal { 2 void speak() {} 3 } 4 5 class Dog extends Animal { 6 void speak() { 7 System.out.println("woof"); 8 } 9 } 10 11 class Cat extends Animal { 12 void speak() { 13 System.out.println("meow"); 14 } 15 } 16 17 class Bird extends Animal { 18 void speak() { 19 System.out.println("tweet"); Zheng-Liang Lu Java Programming 279 / 294
20 } 21 } 22 23 public class PolymorphismDemo { 24 public static void main(string[] args) { 25 Animal[] zoo = {new Dog(), new Cat(), new Bird()}; 26 for (Animal a: zoo) { 27 a.speak(); 28 } 29 } 30 } Zheng-Liang Lu Java Programming 280 / 294
The final Keyword A final variable is a variable which can be initialized once and cannot be changed later. The compiler makes sure that you can do it only once. A final variable is often declared with static keyword and treated as a constant, for example, Math.PI. A final method is a method which cannot be overridden by subclasses. You might wish to make a method final if it has an implementation that should not be changed and it is critical to the consistent state of the object. A class that is declared final cannot be inherited. Zheng-Liang Lu Java Programming 281 / 294
1 class A { 2 final int x = 1; 3 Example 4 final void foo() { 5 x = x + 1; // oops, you cannot change a final variable 6 System.out.println("old foo"); 7 } 8 } 9 10 final class B extends A { 11 int y = 2; 12 13 // cannot be overrided 14 void foo() { 15 System.out.println("my new foo"); 16 } 17 } 18 19 class C extends B {} // oops, B cannnot be inherited 20 21 22 Zheng-Liang Lu Java Programming 282 / 294
23 public class FinalKeywordDemo { 24 public static void main(string[] args) { 25 26 final B b = new B(); 27 System.out.println(b.x); // output 1 28 b.foo(); 29 30 b.y = 3; // ok 31 b = new B(); // oops, cannot reference to a new object 32 } 33 } Zheng-Liang Lu Java Programming 283 / 294
Abstract Class An abstract class is a class declared abstract. The classes that sit at the top of an object hierarchy are typically abstract classes. 6 These abstract class may or may not have abstract methods, which are methods declared without implementation. More explicitly, the methods are declared without braces, and followed by a semicolon. If a class has one or more abstract methods, then the class itself must be declared abstract. All abstract classes cannot be instantiated. Moreover, abstract classes act as placeholders for the subclass objects. 6 The classes that sit near the bottom of the hierarchy are called concrete classes. Zheng-Liang Lu Java Programming 284 / 294
Example Abstract methods and classes are in italic. In this example, the abstract method draw() and resize() should be implemented depending on the real shape. Zheng-Liang Lu Java Programming 285 / 294
Another IS-A Relationship Not all classes share a vertical relationship. Instead, some are supposed to perform the specific methods without a vertical relationship. Consider the class Bird inherited from Animal and Airplane inherited from Transportation. Both Bird and Airplane are able to be in the sky. So they should perform the method canfly(), for example. By semantics, the method canfly() could not be defined in their superclasses. We need a horizontal relationship. Zheng-Liang Lu Java Programming 286 / 294
Example 1 interface Flyable { 2 void canfly(); // public + abstract 3 } 4 5 abstract class Animal {} 6 7 class Bird extends Animal implements Flyable { 8 public void canfly() { 9 System.out.println("Bird flying..."); 10 } 11 } 12 13 abstract class Transportation {} 14 15 class Airplane extends Transportation implements Flyable { 16 public void canfly() { 17 System.out.println("Airplane flying..."); 18 } 19 } Zheng-Liang Lu Java Programming 287 / 294
1 public class interfacedemo { 2 public static void main(string[] args) { 3 Airplane a = new Airplane(); 4 a.canfly(); 5 6 Bird b = new Bird(); 7 b.canfly(); 8 9 Flyable f = a; 10 f.canfly(); // output Airplane flying... 11 f = b; 12 f.canfly(); // output Bird flying... 13 } 14 } Zheng-Liang Lu Java Programming 288 / 294
Interfaces An interface forms a contract between the object and the outside world. For example, the buttons on the television set are the interface between you and the electrical wiring on the other side of its plastic casing. An interface is also a reference type, just like classes, in which only method signatures are defined. So they can be the types of reference variables! Note that interfaces cannot be instantiated (directly). A class implementing one or multiple interfaces provides method bodies for each defined method signature. This allows a class to play different roles, with each role providing a different set of services. Zheng-Liang Lu Java Programming 289 / 294
Example Zheng-Liang Lu Java Programming 290 / 294
1 interface Driveable { 2 void startengine(); 3 void stopengine(); 4 void accelerate(); 5 void turn(); 6 } 1 class Automobile implements Driveable { 2 public void startengine() {... } 3... // and so on 4 public void honkhorn() {... } 5... 6 } 7 8 class Lawnmower implements Driveable { 9 public void startengine() {... } 10... // and so on 11 public void cutgrass() {... } 12... 13 } Zheng-Liang Lu Java Programming 291 / 294
Properties of Interfaces The methods of an interface are implicitly public. In most cases, the class which implements the interface should implement all the methods defined in the interface. Otherwise, the class should be abstract. An interface can declare only fields which are static and final. You can also define static methods in the interface. A new feature since Java SE 8 allows to define the methods with implementation in the interface. A method with implementation in the interface is declared default. Zheng-Liang Lu Java Programming 292 / 294
An interface can extend another interface, just like a class which can extend another class. However, an interface can extend many interfaces as you need. For example, Driveable and Updateable are good interface names. Common interfaces are Runnable 7, Serializable 8, and Collection 9. 7 Related to multithreading. 8 Aka object serialization where an object can be represented as a sequence of bytes that includes the object s data as well as information about the object s type and the types of data stored in the object. 9 Collections are data structures that are fundamental to all types of programming. Zheng-Liang Lu Java Programming 293 / 294
Timing for Interfaces and Abstract Classes Consider using abstract classes if any of these statements apply to your situation: share code among several closely related classes declare non-static or non-final fields Consider using interfaces if any of these statements apply to your situation: unrelated classes would implement your interface specify the behavior of a particular data type, but not concerned about who implements its behavior take advantage of multiple inheritance Zheng-Liang Lu Java Programming 294 / 294