Example: Count of Points 1 public class Point { 2... 3 private static int numofpoints = 0; 4 5 public Point() { 6 numofpoints++; 7 } 8 9 public Point(int x, int y) { 10 this(); // calling Line 5 11 this.x = x; 12 this.y = y; 13 } 14... 15 } Note that invoking constructors (like Line 10) should be placed in the first statement in one constructor. Zheng-Liang Lu Java Programming 243 / 272
Exercise: Singleton In some situations, you may create the only instance of the class. 1 public class Singleton { 2 3 // Do now allow to invoke the constructor by other classes. 4 private Singleton() {} 5 6 // Will be ready as soon as the class is loaded. 7 private static Singleton INSTANCE = new Singleton(); 8 9 // Only way to obtain this singleton by the outside world. 10 public static Singleton getinstance() { 11 return INSTANCE; 12 } 13 } Zheng-Liang Lu Java Programming 244 / 272
Garbage Collection (GC) 2 Java handles deallocation 1 automatically. Timing: preset period or when memory stress occurs. GC is the process of looking at the heap, identifying if the objects are in use, and deleting those unreferenced objects. An object is unreferenced if the object is no longer referenced by any part of your program. (How?) Simply assign null to the reference to make the object unreferenced. Note that you may invoke System.gc() to execute the deallocation procedure. However, frequent invocation of GC is time-consuming. 1 Release the memory occupied by the unused objects. 2 http://www.oracle.com/webfolder/technetwork/tutorials/obe/ java/gc01/index.html Zheng-Liang Lu Java Programming 245 / 272
finalize() The method finalize() conducts a specific task that will be executed right before the object is reclaimed by GC. For example, closing files and terminating network connections. The finalize() method can be only invoked prior to GC. In practice, it must not rely on the finalize() method for normal operations. (Why?) Zheng-Liang Lu Java Programming 246 / 272
Example 1 public class Garbage { 2 private static int numofobjkilled = 0; 3 4 public void finalize() { 5 numofobjkilled++; 6 } 7 8 public static void main(string[] args) { 9 double n = 1e7; 10 for (int i = 1; i <= n; i++) 11 new Garbage(); // lots of unreferenced objects 12 System.out.println(numOfObjKilled); 13 } 14 } You may try different number for instance creation. The number of the objects reclaimed by GC is uncertain. Zheng-Liang Lu Java Programming 247 / 272
HAS-A Relationship Association is a weak relationship where all objects have their own lifetime and there is no ownership. For example, teacher student; doctor patient. If A uses B, then it is an aggregation, stating that B exists independently from A. For example, knight sword; company employee. If A owns B, then it is a composition, meaning that B has no meaning or purpose in the system without A. For example, house room. Zheng-Liang Lu Java Programming 248 / 272
Example: Lines +2: two Point objects used in one Line object. Zheng-Liang Lu Java Programming 249 / 272
1 public class Line { 2 private Point head, tail; 3 4 public Line(Point p1, Point p2) { 5 head = p1; 6 tail = p2; 7 } 8 10 9 / ignore some methods / 11 public double getlength() { 12 return head.getdistancefrom(tail); 13 } 14 15 public static double measure(line line) { 16 return line.getlength(); 17 } 18 } Zheng-Liang Lu Java Programming 250 / 272
More Examples Circle, Triangle, and Polygon. Book with Authors. Lecturer and Students in the classroom. Zoo with many creatures, say Dog, Cat, and Bird. Channels played on TV. More. Zheng-Liang Lu Java Programming 251 / 272
More About Objects Inheritance: passing down states and behaviors from the parents to their children. Interfaces: requiring objects for the demanding methods which are exposed to the outside world. Polymorphism Packages: grouping related types, and providing access controls and name space management. Immutability Enumeration types Inner classes Zheng-Liang Lu Java Programming 252 / 272
First IS-A Relationship: Inheritance The relationships among Java classes form class hierarchy. We can define new classes by inheriting commonly used states and behaviors from predefined classes. A class is a subclass of some class, which is so-called the superclass, by using the extends keyword. For example, B extends A. In semantics, B is a special case of A, or we could say B specializes A. For example, human and dog are two specific types of animals. When both B and C are subclasses of A, we say that A generalizes B and C. (Déjà vu.) Note that Java allows single inheritance only. Zheng-Liang Lu Java Programming 253 / 272
1 class Animal { 2 3 int weight; 4 Example 5 void eat() { weight++; } 6 void exercise() { weight ; } 7 } 8 9 class Human extends Animal { 10 void writecode() {} 11 } 12 13 class Dog extends Animal { 14 void watchdoor() {} 15 } It is convenient to define, say Cat, by extending Animal. But how could Human and Dog possess those members of Animal? Zheng-Liang Lu Java Programming 254 / 272
Constructor Chaining Once the constructor is invoked, JVM will invoke the constructor of its superclass (recursively). 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. In this sense, we could say that every class is an immediate or a distant subclass of Object. Zheng-Liang Lu Java Programming 255 / 272
Illustration for Class Hierarchy 3 3 See Fig. 3-1 in p. 113 of Evans and Flanagan. Zheng-Liang Lu Java Programming 256 / 272
Example: An Evidence 1 class A { 2 A() { System.out.println("A is creating..."); } 3 } 4 5 class B extends A { 6 B() { 7 super(); // you don t need to do this unless necessary. 8 System.out.println("B is creating..."); 9 } 10 } 11 12 public class ConstructorChainingDemo { 13 public static void main(string[] args) { 14 B b = new B(); 15 } 16 } Zheng-Liang Lu Java Programming 257 / 272
super Recall that this is used to refer to the object itself. You can use super to refer to (non-private) members of the superclass. Note that super() can be used to invoke the constructor of its superclass, just similar to this(). Zheng-Liang Lu Java Programming 258 / 272
Method Overriding (1/2) A subclass is defined to implement the behavior inherited from its superclass. Can you smell it? For example, tostring() is inherited from Object. This method will be invoked by println(). It returns the hashcode 4 of the object by default. It could be overridden so it returns a string of desirable information. Another example we have encountered is finalize(). 4 See https://en.wikipedia.org/wiki/java_hashcode(). Zheng-Liang Lu Java Programming 259 / 272
Example Zheng-Liang Lu Java Programming 260 / 272
Method Overriding (2/2) The requirement of method overriding is as follows: Method signature identical to the one of its superclass; Same return type; Non-reduced visibility relative to the one of its superclass. Note that you cannot override the static methods. You could invoke the overridden method by using super. You should use the annotation 5 @Override to help you. 1 class Cat extends Animal { 2 3 @Override 4 void eat() { weight += 2; } 5 6 } 5 See https://docs.oracle.com/javase/tutorial/java/annotations/. Zheng-Liang Lu Java Programming 261 / 272
Polymorphism 7 The word polymorphism literally means many forms. Java allows 4 types of polymorphism: coercion (casting) ad hoc polymorphism (overloading) subtype polymorphism parametric polymorphism (generics) 6 Subtype polymorphism allows you to create a single interface to different types (implementations). How to make a single interface for different types? Use the superclass of those types as the placeholder. 6 We will introduce Java generics in Java Programming 2. Stay tuned. 7 Also read http://www.javaworld.com/article/3033445/learn-java/ java-101-polymorphism-in-java.html. Zheng-Liang Lu Java Programming 262 / 272
Example: Dependency Reduction (Decoupling) 1 class Student { 2 void domyjob() { / Do not know the detail yet. /} 3 } 4 5 class HighSchoolStudent extends Student { 6 void dohomework() {} 7 8 @Override 9 void domyjob() { dohomework(); } 10 } 11 12 class CollegeStudent extends Student { 13 void writefinalreports() {} 14 15 @Override 16 void domyjob() { writefinalreports(); } 17 } Zheng-Liang Lu Java Programming 263 / 272
1 public class PolymorphismDemo { 2 3 public static void main(string[] args) { 4 HighSchoolStudent h = new HighSchoolStudent(); 5 gostudy(h); 6 CollegeStudent c = new CollegeStudent(); 7 gostudy(c); 8 } 9 10 public static void gostudy(student s) { 11 s.domyjob(); 12 } 13 14 / no need to write these methods 15 public static void gostudy(highschoolstudent s) { 16 s.dohomework(); 17 } 18 19 public static void gostudy(collegestudent s) { 20 s.writefinalreports(); 21 } 22 / 23 } Zheng-Liang Lu Java Programming 264 / 272
Why OOP? First, you may know that there are many programming paradigms. 8 OOP is the solid foundation of modern software design. In particular, encapsulation, inheritance, and polymorphism provide a great reuse mechanism and a great abstraction. Encapsulation isolates the internals (private members) from the externals, fulfilling the abstraction and providing the sufficient accessibility (public methods). Inheritance provides method overriding w/o changing the method signature. 9 Polymorphism exploits the superclass as a placeholder to manipulate the implementations (sub-type objects). 8 See https://en.wikipedia.org/wiki/programming_paradigm. 9 This leads to the need of single interface as mentioned before. Zheng-Liang Lu Java Programming 265 / 272
This lead to the production of frameworks 10, which actually do most of the job, leaving the (application) programmer only with the job of customizing with business logic rules and providing hooks into it. This greatly reduces programming time and makes feasible the creation of larger and larger systems. In analog, we often manipulate objects in an abstract level; we don t need to know the details when we use them. For example, computers, cellphones, driving. 10 See https://spring.io/. Zheng-Liang Lu Java Programming 266 / 272
Another Example 1 class Animal { 2 / ignore the previous part / 3 void speak() {} 4 } 5 6 class Dog extends Animal { 7 / ignore the previous part / 8 @Override 9 void speak() { System.out.println("woof"); } 10 } 11 12 class Cat extends Animal { 13 / ignore the previous part / 14 @Override 15 void speak() { System.out.println("meow"); } 16 } 17 18 class Bird extends Animal { 19 / ignore the previous part / 20 @Override 21 void speak() { System.out.println("tweet"); } 22 } Zheng-Liang Lu Java Programming 267 / 272
1 public class PolymorphismDemo { 2 3 public static void main(string[] args) { 4 5 Animal[] animals = {new Dog(), new Cat(), new Bird()}; 6 for (Animal each: animals) 7 each.speak(); 8 9 } 10 11 } Zheng-Liang Lu Java Programming 268 / 272
Subtype Polymorphism For convenience, let U be a subtype of T. Liskov Substitution Principle states that T-type objects may be replaced with U-type objects without altering any of the desirable properties of T (correctness, task performed, etc.). 11,12 In other words, the references are clients asking the objects (right-hand side) for services! 11 See https://en.wikipedia.org/wiki/liskov_substitution_principle. 12 Also see https://en.wikipedia.org/wiki/solid_(object-oriented_design). Zheng-Liang Lu Java Programming 269 / 272
Casting Upcasting (widening conversion) is to cast the U object/variable to the T variable. 1 U u1 = new U(); // trivial 2 T t1 = u1; // ok 3 T t2 = new U(); // ok Downcasting (narrow conversion) is to cast the T variable to a U variable. 1 U u2 = (U) t2; // ok, but dangerous. why? 2 U u3 = new T(); // error! why? Zheng-Liang Lu Java Programming 270 / 272
Solution: instanceof Upcasting is always allowed, but downcasting is not always true even when you use the cast operator. In fact, type checking at compile time is unsound just because the cast operator violets the functionality of type checking. Moreover, T-type reference can also point to the siblings of U-type. Recall that T-type is used as the placeholder. We can use instanceof to check if the referenced object is of the target type at runtime. Zheng-Liang Lu Java Programming 271 / 272
1 class T {} 2 class U extends T {} 3 class W extends T {} 4 5 public class InstanceofDemo { 6 Example 7 public static void main(string[] args) { 8 10 9 T t = new U(); 11 System.out.println(t instanceof T); // output true 12 System.out.println(t instanceof U); // output true 13 System.out.println(t instanceof W); // output false 14 15 W w = new W(); 16 17 System.out.println(w instanceof T); // output true 18 System.out.println(w instanceof U); // output false 19 System.out.println(w instanceof W); // output true 20 21 } 22 } Zheng-Liang Lu Java Programming 272 / 272