Inheritance
Inheritance
One of the pillars of object-orientation. A new class is derived from an existing class: 1) existing class is called super-class 2) derived class is called sub-class A sub-class is a specialized version of its superclass: 1) has all non-private members of its super-class 2) may provide its own implementation of superclass methods Objects of a sub-class are a special kind of objects of a super-class.
1
Inheritance Syntax
Syntax: class sub-class extends super-class { } Each class has at most one super-class; no multi-inheritance in Java. No class is a sub-class of itself.
2
Example: Super-Class
class A { int i; void showi() { System.out.println("i: " + i); } }
3
Example: Sub-Class
class B extends A { int j; void showj() { System.out.println(j: " + j); } void sum() { System.out.println("i+j: " + (i+j)); } }
4
Class B has no access to the As private variable j. This program will not compile:
class Box { double width, height, depth; Box(double w, double h, double d) { width = w; height = h; depth = d; } Box(Box b) { width = b.width; height = b.height; depth = b.depth; } double volume() { return width * height * depth; } }
8
class BoxWeight extends Box { double weight; BoxWeight(double w, double h, double d, double m) { width = w; height = h; depth = d; weight = m; } BoxWeight(Box b, double w) { Box(b); weight = w; } } Box is a super-class, BoxWeight is a sub-class.
9
Another Sub-Class
Once a super-class exists that defines the attributes common to a set of objects, it can be used to create any number of more specific sub-classes. The following sub-class of Box adds the color attribute instead of weight: class ColorBox extends Box { int color; ColorBox(double w, double h, double d, int c) { width = w; height = h; depth = d; color = c; } }
11
class SuperClass { } class SubClass extends SuperClass { } SuperClass o1; SubClass o2 = new SubClass(); o1 = o2; However, the inverse is illegal: o2 = o1;
12
13
plainbox variable now refers to the WeightBox object. Can we then access this objects weight variable through plainbox? No. The type of a variable, not the object this variable refers to, determines which members we can access! This is illegal: System.out.print("Weight of plainbox is ); System.out.println(plainbox.weight);
14
Super as a Constructor
super(parameter-list);
16
18
Uses of Super
Two uses of super: 1) to invoke the super-class constructor super(); 2) to access super-class members super.variable; super.method(); (1) was discussed, consider (2).
19
class B extends A { int i = 2; System.out.println(i is + i); } The re-declared variables/methods hide those of the super-class.
20
21
22
class Box { private double width, height, depth; Box(double w, double h, double d) { width = w; height = h; depth = d; } Box(Box ob) { width = ob.width; height = ob.height; depth = ob.depth; } double volume() { return width * height * depth; } }
23
24
25
26
} }
27
Constructor Call-Order
Constructor call-order: 1) first call super-class constructors 2) then call sub-class constructors In the sub-class constructor, if super() is not used explicitly, Java calls the default, parameter-less super-class constructor.
28
Exercise: Inheritance 1
1) Define a Class Building for building objects. Each building has a door as one of its components. a) In the class Door, model the fact that a door has a color and three states, "open" , "closed", "locked and unlocked". To avoid illegal state changes, make the state private, write a method (getState) that inspects the state and four methods (open, close, lock and unlock) that change the state. Initialize the state to "closed in the constructor. Look for an alternative place for this initialization. b) Write a method enter that visualizes the process of entering the building (unlock door, open door, enter, ...) by printing adequate messages, e.g. to show the state of the door. c) Write a corresponding method quit that visualizes the process of leaving the house. Don't forget to close and lock the door. d) Test your class by defining an object of type Building and visualizing the state changes when entering and leaving the building.
31
Exercise: Inheritance 2
3) Extend question 1 by introducing a subclass HighBuilding that contains an elevator and the height of the building in addition to the components of Building. Override the method enter to reflect the use of the elevator. Define a constructor that takes the height of the building as a parameter. 4) Define a subclass Skyscraper of HighBuilding, where the number of floors is stored with each skyscraper. What happens, if you don't define a constructor for class Skyscraper (Try it)? Write a constructor that takes the number of floors and the height as a parameter. Test the class by creating a skyscraper with 40 floors and using the inherited method enter.
32
Polymorphism
33
Reuse of code: every time a new sub-class is defined, programmers are reusing the code in a super-class. All non-private members of a super-class are inherited by its sub-class: 1) an attribute in a super-class is inherited as-such in a subclass 2) a method in a super-class is inherited in a sub-class: a) as-such, or b) is substituted with the method which has the same name and parameters (overriding) but a different implementation
34
Polymorphism: Behavior
Suppose we have a hierarchy of classes: 1) The top class in the hierarchy represents a common interface to all classes below. This class is the base class. 2) All classes below the base represent a number of forms of objects, all referred to by a variable of the base class type. What happens when a method is invoked using the base class reference? The object responds in accordance with its true type. What if the user pointed to a different form of object using the same reference? The user would observe different behavior. This is polymorphism.
35
Method Overriding
When a method of a sub-class has the same name and type as a method of the superclass, we say that this method is overridden. When an overridden method is called from within the sub-class: 1) it will always refer to the sub-class method 2) super-class method is hidden
36
37
38
39
class B extends A { int k; B(int a, int b, int c) { super(a, b); k = c; } void show() { super.show(); System.out.println("k: " + k); } } The super-class version of show() is called within the sub-classs version.
40
Method overriding occurs only when the names and types of the two methods (super-class and sub-class methods) are identical. If not identical, the two methods are simply overloaded: class A { int i, j; A(int a, int b) { i = a; j = b; } void show() { System.out.println("i and j: " + i + " " + j); } }
41
The show() method in B takes a String parameter, while the show() method in A takes no parameters:
class B extends A { int k; B(int a, int b, int c) { super(a, b); k = c; } void show(String msg) { System.out.println(msg + k); } }
42
43
Overriding is a lot more than the namespace convention. Overriding is the basis for dynamic method dispatch a call to an overridden method is resolved at run-time, rather than compile-time. Method overriding allows for dynamic method invocation: 1) an overridden method is called through the superclass variable 2) Java determines which version of that method to execute based on the type of the referred object at the time the call occurs 3) when different types of objects are referred, different versions of the overridden method will be called.
44
45
46
Overridden method is invoked through the variable of the superclass type. Each time, the version of the callme() method executed depends on the type of the object being referred to at the time of the call:
class Dispatch { public static void main(String args[]) { A a = new A(); B b = new B(); C c = new C(); A r; r = a; r.callme(); r = b; r.callme(); r = c; r.callme(); } }
47
Polymorphism Again
One interface, many behaviors: 1) super-class defines common methods for sub-classes 2) sub-class provides specific implementations for some of the methods of the super-class A combination of inheritance and overriding sub-classes retain flexibility to define their own methods, yet they still have to follow a consistent interface.
48
Example: Polymorphism 1
A class that stores the dimensions of various 2-dimensional objects: class Figure { double dim1; double dim2; Figure(double a, double b) { dim1 = a; dim2 = b; } double area() { System.out.println("Area is undefined."); return 0; } }
49
Example: Polymorphism 2
Rectangle is a sub-class of Figure: class Rectangle extends Figure { Rectangle(double a, double b) { super(a, b); } double area() { System.out.println("Inside Area for Rectangle."); return dim1 * dim2; } }
50
Example: Polymorphism 3
Triangle is a sub-class of Figure: class Triangle extends Figure { Triangle(double a, double b) { super(a, b); } double area() { System.out.println("Inside Area for Triangle."); return dim1 * dim2 / 2; } }
51
Example: Polymorphism 4
Invoked through the Figure variable and overridden in their respective subclasses, the area() method returns the area of the invoking object: class FindAreas { public static void main(String args[]) { Figure f = new Figure(10, 10); Rectangle r = new Rectangle(9, 5); Triangle t = new Triangle(10, 8); Figure figref; figref = r; System.out.println(figref.area()); figref = t; System.out.println(figref.area()); figref = f; System.out.println(figref.area()); } }
52
Abstract Method
Inheritance allows a sub-class to override the methods of its super-class. In fact, a super-class may altogether leave the implementation details of a method and declare such a method abstract: abstract type name(parameter-list);
Two kinds of methods: 1) concrete may be overridden by sub-classes 2) abstract must be overridden by sub-classes It is illegal to define abstract constructors or static methods.
53
54
Abstract Class
A class that contains an abstract method must be itself declared abstract: abstract class abstractClassName { abstract type methodName(parameter-list) { } } An abstract class has no instances - it is illegal to use the new operator:
55
Abstract Sub-Class
A sub-class of an abstract class: 1) implements all abstract methods of its super-class, or 2) is also declared as an abstract class abstract class A { abstract void callMe(); } abstract class B extends A { int checkMe; }
56
57
Calling concrete and overridden abstract methods: class AbstractDemo { public static void main(String args[]) { B b = new B(); b.callme(); b.callmetoo(); } }
58
59
62
Figure figref;
Later, figref may be used to assign references to any object of a concrete sub-class of Figure (e.g. Rectangle) and to invoke methods of this class:
63
Uses of final
The final keyword has three uses: 1) declare a variable which value cannot change after initialization 2) declare a method which cannot be overridden in sub-classes 3) declare a class which cannot have any subclasses (1) has been discussed before. Now is time for (2) and (3).
64
class A { final void meth() { System.out.println("This is a final method."); } } This class declaration is illegal: class B extends A { void meth() { System.out.println("Illegal!"); } }
65
Declaring a class final implicitly declares all its methods final. It is illegal to declare a class as both abstract and final.
66
Object Class
Object class is a super-class of all Java classes: 1) Object is the root of the Java inheritance hierarchy. 2) A variable of the Object type may refer to objects of any class. 3) As arrays are implemented as objects, it may also refer to any array.
67
Methods declared in the Object class: 1) Object clone() - creates an object which is an ideal copy of the invoking object. 2) boolean equals(Object object) - determines if the invoking object and the argument object are the same. 3) void finalize() called before an unused object is recycled 4) Class getClass() obtains the class description of an object at run-time 5) int hashCode() returns the hash code for the invoking object
68
All methods except getClass, notify, notifyAll and wait can be overridden. Two methods are frequently overridden: 1) equals() 2) toString() This way, classes can tailor the equality and the textual description of objects to their own specific structure and needs.
69
Exercise: Polymorphism
1) Define a relationship among the following Building, HighBuilding and Skyscraper classes. 2) Define a class Visits that stores an array of 10 buildings (representing a street). 3) Define a method that enters all the buildings in the street using the method enter, one after another. 4) Fill the array with mixed objects from the classes Building, HighBuilding and Skyscraper. Make sure, that the output of your program visualizes the fact that different method implementations are used depending on the type of the actual object.
70
ACCESS
71
Classes written so far all belong to a single name space: a unique name has to be chosen for each class to avoid name collision. Some way to manage the name space is needed to: 1) ensure that the names are unique 2) provide a continuous supply of convenient, descriptive names 3) ensure that the names chosen by one programmer will not collide with those chosen by another programmers Java provides a mechanism for partitioning the class name space into more manageable chunks. This mechanism is a package.
72
Package
A package is both a naming and a visibility control mechanism: 1) divides the name space into disjoint subsets It is possible to define classes within a package that are not accessible by code outside the package. 2) controls the visibility of classes and their members It is possible to define class members that are only exposed to other members of the same package. Same-package classes may have an intimate knowledge of each other, but not expose that knowledge to other packages.
73
Package Definition
means that all classes in this file belong to the myPackage package. The package statement creates a name space where such classes are stored. When the package statement is omitted, class names are put into the default package which has no name.
74
75
Consider the Java source file: package myPackage; class MyClass1 { } class MyClass2 { }
The bytecode files MyClass1.class and MyClass2.class must be stored in a directory myPackage. Case is significant! Directory names must match package names exactly.
76
Package Hierarchy
To create a package hierarchy, separate each package name with a dot: package myPackage1.myPackage2.myPackage3;
A package hierarchy must be stored accordingly in the file system: 1) Unix myPackage1/myPackage2/myPackage3 2) Windows myPackage1\myPackage2\myPackage3 3) Macintosh myPackage1:myPackage2:myPackage3 You cannot rename a package without renaming its directory!
77
Finding Packages
As packages are stored in directories, how does the Java run-time system know where to look for packages? Two ways: 1) The current directory is the default start point if packages are stored in the current directory or sub-directories, they will be found. 2) Specify a directory path or paths by setting the CLASSPATH environment variable.
78
CLASSPATH Variable
CLASSPATH - environment variable that points to the root directory of the systems package hierarchy. Several root directories may be specified in CLASSPATH, e.g. the current directory and the C:\myJava directory:
.;C:\myJava
Java will search for the required packages by looking up subsequent directories described in the CLASSPATH variable.
79
Finding Packages
Consider this package statement: package myPackage; In order for a program to find myPackage, one of the following must be true: 1) program is executed from the directory immediately above myPackage (the parent of myPackage directory) 2) CLASSPATH must be set to include the path to myPackage
80
Example: Package 1
package MyPack; class Balance { String name; double bal; Balance(String n, double b) { name = n; bal = b; } void show() { if (bal<0) System.out.print("-->> "); System.out.println(name + ": $" + bal); } }
81
Example: Package 2
class AccountBalance { public static void main(String args[]) { Balance current[] = new Balance[3]; current[0] = new Balance("K. J. Fielding", 123.23); current[1] = new Balance("Will Tell", 157.02); current[2] = new Balance("Tom Jackson", -12.33); for (int i=0; i<3; i++) current[i].show(); } }
82
Example: Package 3
Save, compile and execute: 1) call the file AccountBalance.java 2) save the file in the directory MyPack 3) compile; AccountBalance.class should be also in MyPack 4) set access to MyPack in CLASSPATH variable, or make the parent of MyPack your current directory 5) run: java MyPack.AccountBalance Make sure to use the package-qualified class name.
83
Importing of Packages
Since classes within packages must be fully-qualified with their package names, it would be tedious to always type long dot-separated names. The import statement allows to use classes or whole packages directly. Importing of a concrete class: import myPackage1.myPackage2.myClass;
84
Access Control
Classes and packages are both means of encapsulating and containing the name space and scope of classes, variables and methods: 1) packages act as a container for classes and other packages 2) classes act as a container for data and code Access control is set separately for classes and class members.
85
Two levels of access: 1) A class available in the whole program: public class MyClass { } 2) A class available within the same package only: class MyClass { }
86
Four levels of access: 1) a member is available in the whole program: public int variable; public int method() { } 2) a member is only available within the same class: private int variable; private int method() { }
87
88
Complicated? Any member declared public can be accessed from anywhere. Any member declared private cannot be seen outside its class. When a member does not have any access specification (default access), it is visible to all classes within the same package. To make a member visible outside the current package, but only to subclasses of the current class, declare this member protected.
89
90
Example: Access 1
Access example with two packages p1 and p2 and five classes. A public Protection class is in the package p1. It has four variables with four possible access rights:
package p1; public class Protection { int n = 1; private int n_pri = 2; protected int n_pro = 3; public int n_pub = 4;
91
Example: Access 2
public Protection() { System.out.println("base constructor"); System.out.println("n = " + n); System.out.println("n_pri = " + n_pri); System.out.println("n_pro = " + n_pro); System.out.println("n_pub = " + n_pub); } }
92
Example: Access 3
Derived class is in the same p1 package and is the sub-class of Protection. It has access to all variables of Protection except the private n_pri:
package p1; class Derived extends Protection { Derived() { System.out.println("derived constructor"); System.out.println("n = " + n); System.out.println("n_pro = " + n_pro); System.out.println("n_pub = " + n_pub); } }
93
Example: Access 4
SamePackage is in the p1 package but is not a sub-class of Protection. It has access to all variables of Protection except the private n_pri: package p1;
class SamePackage { SamePackage() { Protection p = new Protection(); System.out.println("same package constructor"); System.out.println("n = " + p.n); System.out.println("n_pro = " + p.n_pro); System.out.println("n_pub = " + p.n_pub); } }
94
Example: Access 5
Protection2 is a sub-class of p1.Protection, but is located in a different package package p2. Protection2 has access to the public and protected variables of Protection. It has no access to its private and default-access variables:
package p2; class Protection2 extends p1.Protection { Protection2() { System.out.println("derived other package"); System.out.println("n_pro = " + n_pro); System.out.println("n_pub = " + n_pub); } }
95
Example: Access 6
OtherPackage is in the p2 package and is not a sub-class of p1.Protection. OtherPackage has access to the public variable of Protection only. It has no access to its private, protected or default-access variables:
class OtherPackage { OtherPackage() { p1.Protection p = new p1.Protection(); System.out.println("other package constructor"); System.out.println("n_pub = " + p.n_pub); } }
96
Example: Access 7
A demonstration to use classes of the p1 package: package p1; public class Demo { public static void main(String args[]) { Protection ob1 = new Protection(); Derived ob2 = new Derived(); SamePackage ob3 = new SamePackage(); } }
97
Example: Access 8
A demonstration to use classes of the p2 package: package p2; public class Demo { public static void main(String args[]) { Protection2 ob1 = new Protection2(); OtherPackage ob2 = new OtherPackage(); } }
98
Import Statement
The import statement occurs immediately after the package statement and before the class statement:
package myPackage; import otherPackage1;otherPackage2.otherClass; class myClass { } The Java system accepts this import statement by default: import java.lang.*;
This package includes the basic language functions. Without such functions, Java is of no much use.
99
Name Conflict 1
import otherPackage1.*; import otherPackage2.*; class myClass { otherClass } package otherPackage1; class otherClass { } package otherPackage2; class otherClass { }
100
Name Conflict 2
Compiler will remain silent, unless we try to use otherClass. Then it will display an error message. In this situation we should use the full name:
101
Only the public components in imported package are accessible for nonsub-classes in the importing code!
102
Example: Packages 2
The importing code has access to the public class Balance of the MyPack package and its two public members:
import MyPack.*; class TestBalance { public static void main(String args[]) { Balance test = new Balance("J. J. Jaspers", 99.88); test.show(); } }
103
Finally, a Java source file consists of: 1) a single package instruction (optional) 2) several import statements (optional) 3) a single public class declaration (required) 4) several classes private to the package (optional) At the minimum, a file contains a single public class declaration.
104
Exercise: Access
1) Create a package emacao. Don't forget to insert your package into a directory of the same name. Insert a class AccessTest into this packge. Define public, default and private data members and methods in your class AccessTest. 2) Define a second class Accessor1 in your package that accesses the different kinds of data members of methods (private, public, default). See what compiler messages you get. 3) Define class Accessor2 outside the package. Again try to access all methods and data members of the class AccessTest. See what compiler messages you get. 4) Where are the differences between Accessor1 and Accessor2 ?
105