public Class - Cleveland State University
Download
Report
Transcript public Class - Cleveland State University
Chapter 11
Inheritance and Polymorphism
CIS265/506 Cleveland State University – Prof. Victor Matos
Adapted from: Introduction to Java Programming: Comprehensive Version, Eighth Edition by Y. Daniel Liang
1
Context:
Object Oriented Modeling / Programming
Entities in the
“real world”
Developers
Create classes
Abstracting the
real world
2
Programmers
Motivations
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
3
Example1: Superclasses and Subclasses
4
4
Example1:Superclasses and Subclasses
public abstract class GeometricObject {
1
2
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;
// Return TRUE is object is filled
public boolean isFilled() {
return filled;
}
// Construct a default geometric object
protected GeometricObject() {
dateCreated = new java.util.Date();
}
// Set filled to either: true/false
public void setFilled(boolean filled) {
this.filled = filled;
}
// createa obj with color and filled value
protected GeometricObject(String color,
boolean filled) {
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}
2
// 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;
}
// Return color
public String getColor() {
return color;
}
// Set a new color
public void setColor(String color) {
this.color = color;
}
// Abstract method getArea
public abstract double getArea();
// Abstract method getPerimeter
public abstract double getPerimeter();
5
}
5
4
5
Example1: Superclasses and Subclasses
1
public class Circle4 extends GeometricObject {
private double radius = 1;
/** Return diameter */
public double getDiameter() {
return 2 * radius;
}
public Circle4() {
}
2
public Circle4(double radius) {
super();
this.radius = radius;
}
3
/** Return perimeter */
public double getPerimeter() {
return 2 * radius * Math.PI;
}
public Circle4(double radius,
String color,
boolean filled) {
super(color, filled);
this.radius = radius;
//setColor(color);
//setFilled(filled);
}
3
/* Print the circle info */
public void printCircle() {
System.out.println(toString()
+ " Circle created on: "
+ getDateCreated()
+ " and the radius is " + radius);
}
/** Return radius */
public double getRadius() {
return radius;
}
@Override
public String toString() {
return ">>> Circle " + getColor()
+ "\n" + super.toString()
+ "\n>>> Radius: " + getRadius()
+ " Perimeter: " + getPerimeter()
+ " Area: " + getArea();
}
/** Set a new radius */
public void setRadius(double radius) {
this.radius = radius;
}
6
/** Return area */
public double getArea() {
return radius * radius * Math.PI;
}
6
4
}
5
Example1: Superclasses and Subclasses
1
public class Rectangle1 extends GeometricObject
{
private double width;
private double height;
2
/** Return height */
public double getHeight() {
return height;
}
public Rectangle1() {
}
/** Set a new height */
public void setHeight(double height) {
this.height = height;
}
public Rectangle1(double width,
double height) {
super();
this.width = width;
this.height = height;
}
3
public Rectangle1( double width,
double height,
String color,
boolean filled) {
super(color, filled);
this.width = width;
this.height = height;
// setColor(color);
// setFilled(filled);
}
3
// Return width
public double getWidth() {
return width;
}
7
// Set a new width
public void setWidth(double width) {
this.width = width;
}
7
/** Return area */
public double getArea() {
return width * height;
}
4
/** 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();
}
}
5
Example1: Superclasses and Subclasses
Testing GeometricObject1, Circle4 and Rectangle1 Classes
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() );
}
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
8
8
>>> 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
Invoking Superclass Constructors
•
Constructors could be invoked explicitly or implicitly.
•
Explicit calls use the super keyword
super()
super(arg1, arg2, …)
9
9
•
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.
Obtaining an Object’s Reference
•
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
Package
10
10
Class
‘Location’
Superclass’s Constructor Is Always Invoked
•
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() {
}
public A(double d) {
// some statements
}
public A() {
super();
}
is equivalent to
is equivalent to
public A(double d) {
super();
// some statements
}
11
11
Using the Keyword super
The keyword super refers to the superclass of
the class in which super appears.
This keyword can be used in two ways:
To call a superclass constructor
Super-class
To call a superclass method
super
this
12
12
Sub-class
Constructor Chaining
Creating an instance
of a class invokes all
the superclasses’
constructors along the
inheritance chain.
This is called
constructor chaining.
13
13
Declaring a Subclass
A subclass extends properties and
methods from the superclass.
You can also:
14
14
Add new properties
Add new methods
Override methods of the superclass
Super-class
Sub-class
Calling Superclass Methods
You could rewrite the printCircle() method in the Circle4
class as follows:
public void printCircle() {
System.out.println("The circle is created "
+ super.getDateCreated()
1
+ " and the radius is "
+ radius);
}
15
15
Overriding Methods in the Superclass
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
16
NOTE
• 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
17
Overriding vs. Overloading
public class Test {
public static void main(String[] args) {
A a = new A();
a.p(10);
a.p(10.0);
}
}
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 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);
}
}
class A extends B {
// This method overloads the method in B
public void p(int i) {
System.out.println(i);
}
}
18
18
The Object Class and Its Methods
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 {
...
}
19
19
Equivalent
public class Circle extends Object {
...
}
The Object Class and Its Methods
20
20
The toString() method in Object
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
21
Polymorphism, Dynamic Binding and Generic Programming
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";
}
}
22
22
Polymorphic method m
takes parameters of various
types.
A method that can be applied to
values of different types is called a
polymorphic function.
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.
Console:
Grad. Student
Student
Person
java.lang.Object@9304b1
Dynamic Binding
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
23
Method Matching
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
24
Casting Objects
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:
Object obj = new Student(); // implicit casting
m(obj);
25
25
The statement Object obj = new Student(),
known as implicit casting, is legal because an instance
of Student is automatically an instance of Object.
Why Casting Is Necessary?
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
...
Sms
...
Email
...
Morse
...
26
26
v = (Voice) msg;
s = (Sms)
msg;
e = (Email) msg;
m = (Morse) msg;
Casting from Superclass to Subclass
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;
float f = 123.45;
Specializing
Orange y = (Orange)fruit;
int n = (int) f;
27
27
Observation:
Assume fruit is a “banana”. Both castings will fail.
The numeric example works.
The instanceof Operator
Use the instanceof operator to test whether an object is an
instance of a given class:
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
28
Example2: Demonstrating Polymorphism and Casting
displayGeometricObject displays the area and diameter if the
object is a circle, and displays area if the object is a rectangle.
1
2
3
4
29
29
The equals Method
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
30
NOTE
•
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
31
Useful Predefined Classes: The ArrayList
Java provides the java.util.ArrayList class that can be
used to dynamically store an unlimited number of objects.
32
32
Example3: Using ArrayList 1 of 4
You will get a compilation warning “unchecked operation.” Ignore it for now.
1
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]
0
London
cityList.add("Denver");
// cityList now contains [London, Denver]
cityList.add("Paris");
// cityList now contains [London, Denver, Paris]
0
1
London
Denver
0
1
2
Paris
cityList.add("Miami");
// cityList now contains [London, Denver, Paris, Miami]
cityList.add("Seoul");
// contains [London, Denver, Paris, Miami, Seoul]
London
cityList.add("Tokyo");
// contains [London, Denver, Paris, Miami, Seoul, Tokyo]
33
33
Denver
2
Paris
3
Miami
4
5
Seoul
Tokyo
Example3: Using ArrayList 2 of 4
0
1
London
System.out.println ( "List size? " +
Denver
2
Paris
3
4
Miami
cityList.size() );
Seoul
5
Tokyo
// 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());
34
34
// prints false
Example3: Using ArrayList 3 of 4
0
London
// Insert a new city at index 2
cityList.add(2, "Xian");
0
London
1
Denver
2
3
Paris
1
2
Denver
Xian
Miami
3
Paris
4
Seoul
5
Tokyo
4
Miami
5
Seoul
// Remove a city from the list
cityList.remove("Miami");
0
London
1
Denver
2
Xian
3
Paris
4
Seoul
// Remove a city at index 1
cityList.remove(1);
0
London
1
Xian
2
Paris
// Display the contents in the list
System.out.println ( cityList.toString() );
// print
35
35
[London, Xian, Paris, Seoul, Tokyo]
3
Seoul
4
Tokyo
5
Tokyo
6
Tokyo
Example3: Using ArrayList 4 of 4
0
1
London
2
Xian
Paris
3
4
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) );
0
Circle4 @ abcd1111
1
Circle4 @ abcd2222
// Display the area of the first circle in the list
System.out.println ( "The area of the circle? "
+ ((Circle4)list.get(0)).getArea() );
}
}
36
36
Example4 - A Custom Made Class: MyStack
A stack to hold objects.
37
37
Example4 - A Custom Made Class: MyStack
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);
}
38
38
/** Override the toString in the Object class */
public String toString() {
return "stack: " + list.toString();
}
}
The protected Modifier
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.
private ⟶ default (no modifier is used) ⟶ protected ⟶ public
Visibility increases
39
39
Accessibility Summary
Modifier on
members in a
class
40
40
Accessed
Accessed
from the same from the same
class
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
package p1;
public class C1 {
public int x;
protected int y;
int z;
private int u;
public class C2 {
C1 o = new C1();
can access o.x;
can access o.y;
can access o.z;
cannot access o.u;
protected void m() {
}
}
can invoke o.m();
}
package p2;
public class C3
extends C1 {
can access x;
can access y;
can access z;
cannot access u;
public class C4
extends C1 {
can access x;
can access y;
cannot access z;
cannot access u;
can invoke m();
}
41
41
public class C5 {
C1 o = new C1();
can access o.x;
cannot access o.y;
cannot access o.z;
cannot access o.u;
can invoke m();
}
cannot invoke o.m();
}
A Subclass Cannot Weaken the Accessibility
•
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.
private ⟶ default (no modifier is used) ⟶ protected ⟶ public
Changes of visibility are valid in this direction ⟶
Changes of visibility are invalid in this direction ⟵
42
42
final
43
43
NOTE
•
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 subclassing.
•
A final method cannot be overridden by its subclasses.
Appendix A. Using Eclipse Tool Bar to code a POJO
(Plain Old Java Object)
44
44