Chapter 11 Inheritance and...
Transcript of Chapter 11 Inheritance and...
Chapter 11
Inheritance and Polymorphism
1
CIS265/506 Cleveland State University – Prof. Victor Matos Adapted from: Introduction to Java Programming: Comprehensive Version, Eighth Edition by Y. Daniel Liang
Context:
Object Oriented Modeling / Programming
2
Entities in the
“real world” Programmers
Developers
Create classes
Abstracting the
real world
Motivations
3
Suppose you will define classes to model circles, rectangles,
and triangles. These geometric classes have many common
features.
What is the best way to design these classes so to avoid
redundancy?
The answer is to use object inheritance.
3
Example1: Superclasses and Subclasses
4 4
Example1:Superclasses and Subclasses
5
public abstract class GeometricObject {
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;
// Construct a default geometric object
protected GeometricObject() {
dateCreated = new java.util.Date();
}
// createa obj with color and filled value
protected GeometricObject(String color,
boolean filled) {
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}
// Return color
public String getColor() {
return color;
}
// Set a new color
public void setColor(String color) {
this.color = color;
}
// Return TRUE is object is filled
public boolean isFilled() {
return filled;
}
// Set filled to either: true/false
public void setFilled(boolean filled) {
this.filled = filled;
}
// Get dateCreated
public java.util.Date getDateCreated() {
return dateCreated;
}
// Return a string representing this object
@Override
public String toString() {
return "created on "
+ dateCreated
+ "\ncolor: " + color
+ " and filled: " + filled;
}
// Abstract method getArea
public abstract double getArea();
// Abstract method getPerimeter
public abstract double getPerimeter();
}
2
5
4
5
1
2
Example1: Superclasses and Subclasses
6
public class Circle4 extends GeometricObject {
private double radius = 1;
public Circle4() {
}
public Circle4(double radius) {
super();
this.radius = radius;
}
public Circle4(double radius,
String color,
boolean filled) {
super(color, filled);
this.radius = radius;
//setColor(color);
//setFilled(filled);
}
/** Return radius */
public double getRadius() {
return radius;
}
/** Set a new radius */
public void setRadius(double radius) {
this.radius = radius;
}
/** Return area */
public double getArea() {
return radius * radius * Math.PI;
}
/** Return diameter */
public double getDiameter() {
return 2 * radius;
}
/** Return perimeter */
public double getPerimeter() {
return 2 * radius * Math.PI;
}
/* Print the circle info */
public void printCircle() {
System.out.println(toString()
+ " Circle created on: "
+ getDateCreated()
+ " and the radius is " + radius);
}
@Override
public String toString() {
return ">>> Circle " + getColor()
+ "\n" + super.toString()
+ "\n>>> Radius: " + getRadius()
+ " Perimeter: " + getPerimeter()
+ " Area: " + getArea();
}
}
1
3
3
4
5
2
6
Example1: Superclasses and Subclasses
7
public class Rectangle1 extends GeometricObject
{
private double width;
private double height;
public Rectangle1() {
}
public Rectangle1(double width,
double height) {
super();
this.width = width;
this.height = height;
}
public Rectangle1( double width,
double height,
String color,
boolean filled) {
super(color, filled);
this.width = width;
this.height = height;
// setColor(color);
// setFilled(filled);
}
// Return width
public double getWidth() {
return width;
}
// Set a new width
public void setWidth(double width) {
this.width = width;
}
/** Return height */
public double getHeight() {
return height;
}
/** Set a new height */
public void setHeight(double height) {
this.height = height;
}
/** Return area */
public double getArea() {
return width * height;
}
/** Return perimeter */
public double getPerimeter() {
return 2 * (width + height);
}
@Override
public String toString() {
return "\n>>> Rectangle "
+ getColor()
+ "\n" + super.toString()
+ "\n>>> Height: " + getHeight()
+ " Width: " + getWidth()
+ " Perimeter: " + getPerimeter()
+ " Area: " + getArea();
}
}
1
3
3
4
5
2
7
Example1: Superclasses and Subclasses
8
public static void main(String[] args) throws FileNotFoundException {
// TRY: GeometricObject g1 = new GeometricObject()
Circle4 c1 = new Circle4();
System.out.println( c1.toString() );
Rectangle1 r1 = new Rectangle1();
System.out.println( r1.toString() );
Rectangle1 r2 = new Rectangle1(10,20,"Yellow", true);
System.out.println( r2.toString() );
}
Testing GeometricObject1, Circle4 and Rectangle1 Classes
Console
>>> Circle white created on Tue Jan 24 17:39:45 EST 2012 color: white and filled: false >>> Radius: 1.0 Perimeter: 6.283185307179586 Area: 3.141592653589793 >>> Rectangle white created on Tue Jan 24 17:39:45 EST 2012 color: white and filled: false >>> Height: 0.0 Width: 0.0 Perimeter: 0.0 Area: 0.0 >>> Rectangle Yellow created on Tue Jan 24 17:39:45 EST 2012 color: Yellow and filled: true >>> Height: 20.0 Width: 10.0 Perimeter: 60.0 Area: 200.0 8
Invoking Superclass Constructors
9
• Constructors could be invoked explicitly or implicitly.
• Explicit calls use the super keyword
super()
super(arg1, arg2, …)
• In implicit calls (the keyword super is not used), the
superclass no-arg constructor is automatically invoked.
• If used, the statement super() or super(arguments) must appear in the first line of the subclass constructor.
9
Obtaining an Object’s Reference
10
• A convenient user-defined method returning the reference to
an object is defined below
private String getReference() { return this.getClass().getCanonicalName() + "@" + Integer.toHexString(this.hashCode()); }
• Example: Reference to a Rectangle object is expressed as
csu.matos.Rectangle@5c647e05
10
Package Class ‘Location’
Superclass’s Constructor Is Always Invoked
11
• A constructor may invoke a local overloaded constructor
or its superclass’s constructor(s).
• If none of them is invoked explicitly, the compiler puts super() as the first statement in the constructor. For
example,
public A(double d) {
// some statements
}
is equivalent to
public A(double d) {
super();
// some statements
}
public A() {
}
is equivalent to
public A() {
super();
}
11
Using the Keyword super
12
To call a superclass constructor
To call a superclass method
The keyword super refers to the superclass of
the class in which super appears.
This keyword can be used in two ways:
12
Sub-class
Super-class
super
this
Constructor Chaining
13
Creating an instance
of a class invokes all
the superclasses’
constructors along the
inheritance chain.
This is called
constructor chaining.
13
Declaring a Subclass
14
A subclass extends properties and methods from the superclass. You can also:
Add new properties
Add new methods
Override methods of the superclass
14
Sub-class
Super-class
Calling Superclass Methods
15
You could rewrite the printCircle() method in the Circle4
class as follows:
public void printCircle() { System.out.println("The circle is created " + super.getDateCreated() + " and the radius is " + radius); }
15
1
Overriding Methods in the Superclass
16
Sometimes it is necessary for a subclass to modify the
implementation of a method defined in its superclass.
This is referred to as method overriding.
public Class Rectangle1 extends GeometricObject1 {
// Other methods are omitted . . .
// Override the toString method defined in GeometricObject
public String toString() {
return "\n>>> Rectangle " + getColor()
+ "\n" + super.toString()
+ "\n>>> Height: " + getHeight()
+ " Width: " + getWidth()
+ " Perimeter: " + getPerimeter()
+ " Area: " + getArea();
}
. . .
}
16
NOTE
17
• An instance method can be overridden only if
it is accessible.
• A private method cannot be overridden by a
subclass because it is not accessible outside its
own class.
• A static method cannot be overridden.
17
Overriding vs. Overloading
18
public class Test {
public static void main(String[] args) {
A a = new A();
a.p(10);
a.p(10.0);
}
}
class B {
public void p(double i) {
System.out.println(i * 2);
}
}
class A extends B {
// This method overrides the method in B
public void p(double i) {
System.out.println(i);
}
}
public class Test {
public static void main(String[] args) {
A a = new A(); a.p(10);
a.p(10.0);
}
}
class B {
public void p(double i) {
System.out.println(i * 2);
}
}
class A extends B {
// This method overloads the method in B
public void p(int i) {
System.out.println(i);
}
}
18
The Object Class and Its Methods
19
Every class in Java is descended from the java.lang.Object class.
If no inheritance is specified when a class is defined,
the superclass of the class is Object.
public class Circle {
...
}
Equivalent public class Circle extends Object { ... }
19
The Object Class and Its Methods
20 20
The toString() method in Object
21
toString() method returns a string representation of the object.
The default implementation returns a string holding:
1. a class name of which the object is an instance, 2. the at sign @, and 3. a number (hashcode) representing this object.
Loan loan = new Loan();
System.out.println( loan.toString() );
For this example we get something like: Loan@15037e5
You should override the toString method so that it returns a more meaningful string representation of the object.
21
Polymorphism, Dynamic Binding and Generic Programming
22
In our example which implementation of the toString() method is used will be determined dynamically by the Java Virtual Machine at runtime. This capability is known as dynamic binding.
public class PolymorphismDemo {
public static void main(String[] args) {
m(new GraduateStudent());
m(new Student());
m(new Person());
m(new Object());
}
public static void m(Object x) {
System.out.println(x.toString());
}
}
class GraduateStudent extends Student {
public String toString() {
return "Grad. Student";
}
}
class Student extends Person {
public String toString() {
return "Student";
}
}
class Person extends Object {
public String toString() {
return "Person";
}
}
Polymorphic method m
takes parameters of various
types.
A method that can be applied to
values of different types is called a
polymorphic function.
Console: Grad. Student Student Person java.lang.Object@9304b1
22
Dynamic Binding
23
1. Suppose an object o is an instance of classes C1, C2, ..., Cn-1, and Cn, where C1 is a subclass of C2, C2 is a subclass of C3, ..., and Cn-1 is a subclass of Cn.
2. Cn is the most general class, and C1 is the most specific class.
3. If o invokes a method p, the JVM searches the implementation for the method p in C1, C2, ..., Cn-1 and Cn, in this order, until it is found.
4. Once an implementation is found, the search stops and the first-found implementation is invoked.
23
Method Matching
24
The compiler finds a matching method according to:
1. parameter type,
2. number of parameters, and
3. order of the parameters at compilation time.
Example of different invocation of the pay method
bill.payWith ( 19.99 ) bill.payWith ("Visa", "1234 1234 1234 1234" ); bill.payWith ("two cows" );
24
Object obj = new Student(); // implicit casting m(obj);
Casting Objects
25
Casting can be used to convert an object of one class type to
another within an inheritance hierarchy.
In the preceding section, the statement
m( new Student() );
assigns the object new Student() to a parameter of the
Object type. This statement is equivalent to:
The statement Object obj = new Student(),
known as implicit casting, is legal because an instance
of Student is automatically an instance of Object.
25
Why Casting Is Necessary?
26
1. To tell the compiler that an object should be treated as of a particular type you use an explicit casting.
2. In the example below, msg is a block of binary data that could be interpreted in different ways depending on the casting applied on it.
Object msg = ChunkOfBinaryData();
Voice v = (Voice) msg;
...
Sms s = (Sms) msg;
...
Email e = (Email) msg;
...
Morse m = (Morse) msg;
...
26
Casting from Superclass to Subclass
27
Explicit casting must be used when casting an object
from a superclass to a subclass.
This type of casting may not always succeed.
Apple x = (Apple)fruit;
Orange y = (Orange)fruit;
float f = 123.45;
int n = (int) f;
27
Sp
ecia
lizin
g
Observation:
Assume fruit is a “banana”. Both castings will fail.
The numeric example works.
The instanceof Operator
28
Object myObject = new Circle();
// Some lines of code here . . .
// Perform casting if myObject is an instance of Circle
if (myObject instanceof Circle) {
System.out.println("The circle diameter is " +
( (Circle)myObject ).getDiameter() );
...
}
28
Use the instanceof operator to test whether an object is an
instance of a given class:
Example2: Demonstrating Polymorphism and Casting
29
displayGeometricObject displays the area and diameter if the object is a circle, and displays area if the object is a rectangle.
29
1
2
3
4
The equals Method
30
The equals() method compares the contents of two objects
object1.equals ( object2 )
The default implementation of the equals method in the Object class is as follows:
public boolean equals ( Object otherObject ) { return ( this == otherObject ); }
The equals method could be overridden in our Circle example as:
public boolean equals ( Object otherObject ) { if (otherObject instanceof Circle) { return this.getRadius() == ((Circle)otherObject).getRadius(); } else return false; }
30
NOTE
31
• The == comparison operator is used for comparing two primitive
data type values or for determining whether two objects have the
same references.
• The equals method is intended to test whether two objects have
the same contents, provided that the method is modified in the
defining class of the objects.
31
Useful Predefined Classes: The ArrayList
32
Java provides the java.util.ArrayList class that can be used to dynamically store an unlimited number of objects.
32
Example3: Using ArrayList 1 of 4
33
You will get a compilation warning “unchecked operation.” Ignore it for now.
public class TestArrayList { public static void main(String[] args) {
// Create a list to store cities java.util.ArrayList cityList = new java.util.ArrayList();
// Add some cities in the list cityList.add("London"); // cityList now contains [London] cityList.add("Denver"); // cityList now contains [London, Denver] cityList.add("Paris"); // cityList now contains [London, Denver, Paris] cityList.add("Miami"); // cityList now contains [London, Denver, Paris, Miami] cityList.add("Seoul"); // contains [London, Denver, Paris, Miami, Seoul] cityList.add("Tokyo"); // contains [London, Denver, Paris, Miami, Seoul, Tokyo]
33
1
London
London Denver Paris
London Denver Paris Miami Seoul Tokyo
0
0 1 2
0 1 2 3 4 5
Example3: Using ArrayList 2 of 4
34
System.out.println ( "List size? " + cityList.size() ); // prints 6 System.out.println ( "Is Miami in the list? “
+ cityList.contains("Miami") ); // prints true System.out.println ( "The location of Denver in the list? "
+ cityList.indexOf ("Denver") ); // prints 1 System.out.println ( "Is the list empty? "
+ cityList.isEmpty()); // prints false
34
London Denver Paris Miami Seoul Tokyo
0 1 2 3 4 5
// Insert a new city at index 2
cityList.add(2, "Xian");
// Remove a city from the list
cityList.remove("Miami");
// Remove a city at index 1
cityList.remove(1);
// Display the contents in the list
System.out.println ( cityList.toString() );
// print [London, Xian, Paris, Seoul, Tokyo]
Example3: Using ArrayList 3 of 4
35 35
London Denver Paris Miami Seoul Tokyo
0 1 2 3 4 5
London Denver Xian Paris Miami Seoul Tokyo
0 1 2 3 4 5 6
London Denver Xian Paris Seoul Tokyo
0 1 2 3 4 5
0 1 2 3 4
London Xian Paris Seoul Tokyo
// Display the contents in the list in reverse order
for (int i = cityList.size() - 1; i >= 0; i--)
System.out.print( cityList.get(i) + " " );
System.out.println();
// print Tokyo Seoul Paris Xian London
// Create a list to store two circles
java.util.ArrayList list = new java.util.ArrayList();
// Add two circles
list.add ( new Circle4(2) );
list.add ( new Circle4(3) );
// Display the area of the first circle in the list
System.out.println ( "The area of the circle? "
+ ((Circle4)list.get(0)).getArea() );
}
}
Example3: Using ArrayList 4 of 4
36 36
0 1 2 3 4
London Xian Paris Seoul Tokyo
0 1
Circle4 @ abcd1111 Circle4 @ abcd2222
Example4 - A Custom Made Class: MyStack
37
A stack to hold objects.
37
Example4 - A Custom Made Class: MyStack
38
public class MyStack {
private java.util.ArrayList list = new java.util.ArrayList();
public boolean isEmpty() {
return list.isEmpty();
}
public int getSize() {
return list.size();
}
public Object peek() {
return list.get(getSize() - 1);
}
public Object pop() {
Object obj = list.get(getSize() - 1);
list.remove(getSize() - 1);
return obj;
}
public void push(Object obj) {
list.add(obj);
}
public int search(Object obj) {
return list.lastIndexOf(obj);
}
/** Override the toString in the Object class */
public String toString() {
return "stack: " + list.toString();
}
} 38
The protected Modifier
39
The protected modifier can be applied on data and methods in a class.
A protected data or method in a public class can be accessed by any class in the same package or its subclasses, even if the subclasses are in a different package.
39
private ⟶ default (no modifier is used) ⟶ protected ⟶ public
Visibility increases
Accessibility Summary
40 40
Modifier on
members in a
class
Accessed
from the same
class
Accessed
from the same
package
Accessed
from a
subclass
Accessed
from a
different
package
public Yes Yes Yes Yes
protected Yes Yes Yes No
default Yes Yes No No
private Yes No No No
Visibility Modifiers
41
public class C1 {
public int x;
protected int y;
int z;
private int u;
protected void m() {
}
}
public class C2 {
C1 o = new C1();
can access o.x;
can access o.y;
can access o.z;
cannot access o.u;
can invoke o.m();
}
public class C3
extends C1 {
can access x;
can access y;
can access z;
cannot access u;
can invoke m();
}
package p1;
public class C4
extends C1 {
can access x;
can access y;
cannot access z;
cannot access u;
can invoke m();
}
package p2;
public class C5 {
C1 o = new C1();
can access o.x;
cannot access o.y;
cannot access o.z;
cannot access o.u;
cannot invoke o.m();
}
41
A Subclass Cannot Weaken the Accessibility
42
• A subclass may override a protected method in its superclass
and change its visibility to public.
• However, a subclass cannot weaken the accessibility of a
method defined in the superclass.
• For example, if a method is defined as public in the
superclass, it must be defined as public in the subclass.
42
private ⟶ default (no modifier is used) ⟶ protected ⟶ public
Changes of visibility are valid in this direction ⟶ Changes of visibility are invalid in this direction ⟵
final NOTE
43
• Modifiers (private, public, protected, default) are
used on classes, methods, and class variables.
• The final modifier can also be used on local variables in a
method.
• A final local variable is a constant inside a method.
• A final class is one that cannot be extended by sub-
classing.
• A final method cannot be overridden by its subclasses.
43
Appendix A. Using Eclipse Tool Bar to code a POJO (Plain Old Java Object)
44 44