3 (Autosaved)

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 105

Chapter 11

Inheritance and Polymorphism

1
Objectives
 To develop a subclass from a superclass through inheritance
(§11.2).
 To invoke the superclass’s constructors and methods using the
super keyword (§11.3).
 To override instance methods in the subclass (§11.4).
 To distinguish differences between overriding and overloading
(§11.5).
 To explore the toString() method in the Object class (§11.6).
 To discover polymorphism and dynamic binding (§§11.7-11.8).
 To describe casting and explain why explicit downcasting is
necessary (§11.9).
 To explore the equals() method in the Object class (§11.10).
 To restrict access to data and methods to subclasses using the
protected visibility modifier (§11.13).
 To prevent class extending and method overriding using the final
modifier (§11.14).

2
Motivations
 Suppose we want to define classes to model
circles and rectangles. What are the attributes
of each class? Is there common attributes?

– Color = Red  Color =Green


 Filled = Yes  Filled = No
 Radius =3  Width = 4
 Height= 3 3
Motivations
Circle Rectangle
-color: String -color: String
-filled: b o o l e a n -filled: b o o l e a n
-radius: double -width: double
+Circle()
-height: double
+Circle(radius: double) +Rectangle()
+Circle(radius: double, color: String,
filled: b o o l ean ) +Rectangle(width: double, height:
double)
+getRadius(): double
+Rectangle(width: double, height:
+setRadius(radius: double): void d o u b l e color: String, filled:
+getColor(): String boolean)
+setColor(color: String): void +getWidth(): d o u b l e
+isFilled(): boolean +setWidth(width: double): void
+setFilled(filled: boolean): void +getHeight(): double
+getArea(): double +setHeight(height: double): void
+getColor(): String
+getPerimeter(): double
+setColor(color: String): void
+getDiameter(): double
+isFilled(): boolean
+setFilled(filled: boolean): void
 What is the best way to design +getArea(): double
+getPerimeter(): double
these classes to avoid
redundancy?
– The answer is by using inheritance.
4
Motivations
Class Shape

Parent Class
 Color
 Filled

Class Circle Class Rectangle Child Classes

 Width
 Radius  Height
5
Inheritance
 Inheritance can be defined as the process where
one class acquires the properties (methods and
data fields) of another class.
 The class which inherits the properties of other is
known as subclass (child class, derived class)
 The class whose properties are inherited is
known as superclass (parent class, base class).
 Software reuse is a fundamental benefit of
inheritance
6
Inheritance
 Inheritance relationships are shown in a UML class
diagram as shown

Shape

Circle

 The child class inherits the methods and data defined


by the parent class. It can also add new variables and
methods.
7
UML for Circle & Rectangle

8
extends Keyword
 extends is the keyword used to inherit the
properties of a class. Below given is the syntax
of extends keyword.
class Super{ Super
.....
.....
}
class Sub extends Super{ Sub
.....
.....
}
9
Types of Inheritance
 There are many types of inheritance: single
inheritance, multiple inheritance, multilevel
inheritance and hierarchical inheritance

10
Inheritance in Java
 Java supports Only one inheritance, meaning
that a derived class can have only one parent
class
 Multiple inheritance allows a class to be derived
from two or more classes, inheriting the
members of all parents.
 Java does not support multiple inheritance
 Multilevel and hierarchical inheritance can be
used in java.
11
Example of Inheritance
class A {
public void methodA()
{
System.out.println("Base class method");
}
} A

class B extends A{
public void methodB()
{
System.out.println("Child class method");
B
}
}
public class Test {
public static void main(String args[])
{
B obj = new B();
obj.methodA(); //calling super class method
obj.methodB(); //calling local method
}} 12
Check Point
In the previous example, is it allowed to add the
following code to the main method? What is the
wrong?
A obj2 = new A();
obj2.methodA();
obj2.methodB();

13
Are superclass’s Constructor
Inherited?
No. They are not inherited.
– A constructor is used to construct an instance of a
class.
– Unlike properties and methods, a superclass's
constructors are not inherited in the subclass.
They are invoked explicitly or implicitly.
– Explicitly using the super keyword.
– If the keyword super is not explicitly used, the
superclass's no-arg constructor is automatically
invoked.
14
Superclass’s Constructor Is Always
Invoked
A constructor may invoke an overloaded
constructor or its superclass’s constructor. If none
of them is invoked explicitly, the compiler puts
super()as the first statement in the constructor.
For example,

15
Using the Keyword super
The keyword super refers to the superclass of
the class in which super appears.
super keyword can be used in two ways:
– To call a superclass constructor
– To call a superclass methods and variables
You must use the keyword super to call the
superclass constructor.
– Invoking a superclass constructor’s name in a
subclass causes a syntax error
– Note that: Java requires that the statement that uses
the keyword super appear first in the constructor.
16
Caution
 Since the call to another constructor must be the
very first thing you do in the constructor
– You can use this(...) to call another constructor in the same
class:
– class Foo extends Bar {
Foo(String message) { // constructor
this(message, 0, 0); // your explicit call to another constructor
...
– You can use super(...) to call a specific superclass
constructor
– class Foo extends Bar {
Foo(String name) { // constructor
super(name, 5); // your explicit call to some superclass constructor
...

17
Caution
 If a class is designed to be extended, it is better to
provide a no-arg constructor to avoid programming
errors. Consider the following code:
public class Apple extends Fruit {
}
class Fruit {
public Fruit(String name) {
System.out.println("Fruit's constructor is invoked");
}}
Since no constructor is explicitly defined in Apple, Apple’s default no-arg
constructor is defined implicitly. Since Apple is a subclass of Fruit, Apple’s
default constructor automatically invokes Fruit’s no-arg constructor. However,
Fruit does not have a no-arg constructor, because Fruit has an explicit
constructor defined. Therefore, the program cannot be compiled.
18
Check Point
 Is the given code correct?
public class Shape {
public Shape () {… }


public Shape (String color, boolean
filled) {…..}
}//
*************************************
**
public class Circle extends Shape{
public Circle() { }
// invisible} call to superclass constructor
If the keyword super is not explicitly used, the superclass's
no-arg constructor is automatically invoked.
19
Check Point
 Is the given code correct?
public class Shape {
public Shape () {… }


public Shape (String color, boolean
filled) {…..}
}//
*************************************
**
public class Circle extends Shape{
public Circle(double radius) {
// invisible callthis.radius
to superclass constructor
= radius;}}

20
Check Point
 Is the given code correct?
public class Shape {
public Shape (String color, boolean

x
filled) {…..}
}//
************************************
***
public class Circle extends Shape{
public Circlet() { }
}
If no such call exists , Java will automatically make a call to
super() at the beginning of the constructor, if there exist an
empty constructor.
21
Check Point
 Is the given code correct?
public class Shape {


}//
************************************
***
public class Circle extends Shape{
public Circlet() { }
}

If no such call exists , Java will automatically make a call to


default super() at the beginning of the constructor, as no
constructors in the parent class.
22
Check Point
 Is the given code correct?
public class Shape {
public Shape () {… }

x
public Shape (String color, boolean
filled) {…..}
}//
************************************
***
public class Circle extends Shape{
public Circlet() {this.radius = 0;
super
The first line of a(“Red”,true) }}
child’s constructor should use the super
reference to call the parent’s constructor

23
Check Point
 Is the given code correct?
public class Shape {
public Shape () {… }


public Shape (String color, boolean
filled) {…..}
}//
************************************
***
public class Circle extends Shape{
}
If no such call exists , Java will automatically make a call to
super() at the beginning of the constructor, if there exist an
empty constructor.
24
Constructor Chaining
Constructing an instance of a class invokes all the
superclasses’ constructors along the inheritance
chain. This is called constructor chaining.
Person

Employee

Faculty

25
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty(); 1. Start from the
} main method
public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

26
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty(); 2. Invoke Faculty
} constructor
public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

27
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}
3. Invoke Employee’s no-
class Employee extends Person {
public Employee() {
arg constructor
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

28
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person { 4. Invoke Employee(String)


public Employee() { constructor
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

29
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
5. Invoke Person()
public Person() { constructor
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

30
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() { 6. Execute println
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

31
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() { 7. Execute println
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

32
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() { 8. Execute println
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

33
Trace Execution
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println("(4) Faculty's no-arg constructor is invoked");
}
}

class Employee extends Person { 9. Execute println


public Employee() {
this("(2) Invoke Employee’s overloaded constructor");
System.out.println("(3) Employee's no-arg constructor is invoked");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}

34
Declaring a Subclass
A subclass extends properties and methods from
the superclass. It can also:
– Add new properties
– Add new methods
– Override the methods of the superclass

35
Method Overriding
Considerthat we want to define classes to
model circle and cylinder using inheritance.
Circle
- radius
+Cirlce ()
+getRadius ()
+ getArea ()
  Radius
Radius
  getArea ()
getArea () Cylinder
- height
 Height= 3 +Cylinder ()
+getHeight ()

Is that correct??
36
Method Overriding
The area of the circle is (r2 π) where the area of
the cylinder is (2 π r h + 2 π r2)
Therefore, we need to have a new version of
getArea() in the cylinder class Circle
- radius
– We need to override the method! +Cirlce ()
+getRadius ()
– Modify the implementation of a + getArea ()
method defined in the superclass is
referred to as method overriding. Cylinder
- height
+Cylinder ()
+getHeight ()
+getArea ()
37
Method Overriding & Variable
Hiding
A subclass inherits all the member variables and
methods from its super classes.
It can use the inherited methods and variables as
they are.
It may also override an inherited method by
providing its own version
It may also hide an inherited variable by defining
a variable of the same name.

38
Overriding vs. Overloading
Overridden methods are in different classes related
by inheritance; overloaded methods can be either
in the same class or different classes related by
inheritance.
Overridden methods have the same signature and
return type; overloaded methods have the same
name but a different parameter list.

39
Overriding vs. Overloading
What is the output of the following programs?
public class Test { public class Test {
public static void main(String[] args) { public static void main(String[] args) {
A a = new A(); A a = new A();
a.p(10); a.p(10);
a.p(10.0); a.p(10.0);
} }
} }

class B { class B {
public void p(double i) { public void p(double i) {
System.out.println(i * 2); System.out.println(i * 2);
} }
} }

class A extends B { class A extends B {


// This method overrides the method in B // This method overloads the method in B
public void p(double i) { public void p(int i) {
System.out.println(i); System.out.println(i);
} }
} }
40
Caution
 Override method: is the new version (behavior)
of the old one. How can we reuse the old method
plus adding the new behavior ?
public class Shape {

……

public String toString() {


return "created on " + dateCreated + "\ncolor: " + color + " and filled: " + filled; }
}

public class Circle extends Shape{


private double radius;

public String toString() {

}}
41
Calling Superclass Methods
super.methodName(args);

public class Shape {

……

public String toString() {


return "created on " + dateCreated + "\ncolor: " + color + " and filled: " + filled; }
}

public class Circle extends Shape{


private double radius;

public String toString() {


return "The circle is created " + super.toString()+ " and the radius is " +radius
}}

42
Note
An instance method can be overridden only if it is
accessible.
– Thus a private method cannot be overridden, because
it is not accessible outside its own class.
Ifa method defined in a subclass is private in its
superclass, the two methods are completely
unrelated.

43
Note
Like an instance method, a static method can be
inherited.
However, a static method cannot be overridden.
Ifa static method defined in the superclass is
redefined in a subclass, the method defined in the
superclass is hidden.
– The hidden static methods can be invoked using the
following syntax:
superClassName.staticMethodName()
44
The protected Modifier
Theprotected modifier can be applied on data
and methods in a class.
A protected data or a protected 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, #protected, +public

45
Accessibility Summary

Modifier Accessed Accessed Accessed Accessed


on members from the from the from a from a different
in a class same class same package subclass package

public

protected -

default - -

private - - -

46
Visibility Modifiers

47
protected Modifier in UML
The # symbol indicates the protected variables and
classes.
Example:

Circle
# radius
+Cirlce ()
+getRadius ()
+ getArea ()

48
Override the Accessibility
What is wrong with this code???
public class Shape {
……..

protected void Print() A Subclass cannot


{ // print the content }
……. weaken the accessibility
} of a method defined in
//***********************************
the superclass
public class Circle extends Shape{

….
x
private void Print () {/** Override the Print method defined in Shape class*/ }
………

}
49
Override the Accessibility
Is this code correct ???
public class Shape {
……..

protected void Print() A subclass may override


{ // print the content }
……. a protected method in its
} superclass and change its
//***********************************
visibility to public


public class Circle extends Shape{

….

public void Print () {/** Override the Print method defined in Shape class*/ }
………

}
50
The final Modifier
 The final variable is a constant:
final static double PI = 3.14159;
– cannot change its value
 The final class:
final class Math {
...
}
– cannot be extended (cannot be inherited)
 The final method:
final void demo() {}
– cannot be overridden by its subclasses.
51
Check Point
 Identify the problems in the following code

52
The Object Class
 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 { public class Circle extends Object {


... Equivalent
...
} }

53
The toString()method in Object
 The toString() method returns a string representation of the
object.
 The default implementation returns a string consisting of
– a class name of which the object is an instance,
– The sign @,
– a number representing this object.

Loan loan = new Loan();


System.out.println(loan.toString());
 // or we can write System.out.println(loan);
The code displays something like Loan@15037e5 .
– This message is not very helpful or informative.
– Usually you should override the toString method so that it
returns a digestible string representation of the object.
54
Implementation for Circle & Rectangle

55
public class Shape {
private String color = ”white" ;
private boolean filled;

/** Construct a default object */


public Shape () {
}
/** Construct an object with the specified attributes
public Shape ( String color, boolean filled)
{ this.color = color; this.filled = filled; }

/** Get and Set color */


public String getColor() { return color; }
public void setColor(String color) { this.color = color; }

/** Get and Set filled. Since filled is boolean, the get is named isFilled */
public boolean isFilled() { return filled; }
public void setFilled(boolean filled) { this.filled = filled; }

/** Return a string representation of this object */


public String toString()
{ return ”color: " + color + " and filled: " + filled; }
}

56
public class Circle extends Shape {
private double radius;
/** Construct a default object */
public Circle () { }

/** Constructs an object with the specified attributes


public Circle (double radius)
{ super(); this.radius = radius; }
public Circle (double radius, String color, boolean filled)
{ super(color, filled); this.radius = radius; }

/** Get and Set radius */


public double getRadius() { return radius; }
public void setRadius( double radius) { this.radius = radius; }

/** Return area of circle*/


public double getArea() { return radius * radius * Math.PI; }

/** Return diameter of circle */


public double getDiameter() {return 2 * radius; }

/** Return perimeter of circle */


public double getPerimeter() {return 2 * radius * Math.PI; }

/** Return a string representation of this object */


public String toString()
{ return “Circle WWW\n" + ”Radius: " + radius + super.toString();} } 57
public class Rectangle extends Shape {
private double width;
private double height;
/** Construct a default object */
public Rectangle () { }
/** Constructs an object with the specified attributes
public Rectangle (double width, double height)
{ this.width = width; this.height = height; }
public Rectangle (double width, double height, String color,
boolean filled){
this.width = width; this.height = height;
setColor(color); setFilled(filled);}

/** Get and Set width*/


public double getWidth() { return width; }
public void setWidth( double width) { this.width = width; }
/** Get and Set height */
public double getHeight() { return height; }
public void setHeight( double height) { this.height = height; }

/** Return area of rectangle*/


public double getArea() { return width * height; }
/** Return perimeter of rectangle*/
public double getPerimeter() {return 2 * (width + height); }
/** Return a string representation of this object */
public String toString()
{ return “Rectangle WWW\n" + ”width: " + width + ”and height: " + height +
58
”\ncolor: " + getColor() + ”and filled : " + isFilled(); } }
public class TestCircleRectangle {
public static void main(String[] args) {
/** Test Circle class*/
Circle circle = new Circle(1);
System.out.println( "A circle " + circle.toString());
System.out.println( "The area is " + circle.getArea());
System.out.println( "The diameter is " + circle.getDiameter());

/** Test Rectangle class*/


Rectangle rectangle = new Rectangle(2, 4);
System.out.println( "\nA rectangle " + rectangle.toString());
System.out.println("The area is " + rectangle.getArea());
System.out.println( "The perimeter is " + rectangle.getPerimeter());
}
}

59
Polymorphism
 Polymorphism means many (poly) shapes
(morph)
 The term polymorphism literally means "having
many forms“
 Polymorphism means that a variable of a
supertype can refer to a subtype object.

60
Animals make sounds
 The Animal class is used
to derive classes called
Cat, Dog and Duck.
 All Animals make sounds.
But each one has its own
sound. Animal
sound()
 Therefore, Animal
Dog Cat Duck
reference could be used to sound() sound() sound()
point to a Cat, Dog and
Duck objects. 61
References and Inheritance
 An object reference can refer to an object of its
class, or to an object of any class related to it by
inheritance
Animal animal = new Cat();
animal.sound(); The method invoked
animal = new Duck(); through a polymorphic
animal.sound(); reference can change from
animal = new Dog(); one invocation to the next
animal.sound();
 It is the type of the object being referenced, not
the reference type, that determines which method
is invoked.
62
Example
public class PolymorphismDemo { Shape
/** Main method */
public static void main(String[] args) {

// Display circle and rectangle properties Rectangle Circle


displayObject(new Circle (1, "red", false));
displayObject(new Rectangle (1, 1, "black", true));
}

/** Display geometric object properties */


public static void displayObject(Shape object)
{
System.out.println(”Is filled? " + object.isFilled() +
". Color is " + object.getColor());
}
}
63
Supertype and Subtype
 A type defined by a subclass is called a subtype.
 A type defined by its superclass is called a
supertype.
 Therefore, you can say that Circle is a subtype of
Shape and Shape is a supertype for Circle.
Shape

Circle
64
Polymorphism
class Person { public class PolymorphismDemo {
public String toString() { public static void
return "Person"; main(String[] args) {
}
} m(new GraduateStudent());
//**************************** m(new Student());
class Student extends Person { m(new Person());
public String toString() { m(new Object());
return "Student"; }
}
} public static void m(Object x) {
//****************************
class GraduateStudent System.out.println(x.toString());
extends Student { }
} }

Method m takes a
An object of a subtype can be used wherever its parameter of the Object
supertype value is required. This feature is type. You can invoke it
known as polymorphism. with any object.
65
Dynamic Binding
class Person { public class PolymorphismDemo {
public String toString() { public static void
return "Person"; main(String[] args) {
}
} m(new GraduateStudent());
//**************************** m(new Student());
class Student extends Person { m(new Person());
public String toString() { m(new Object());
return "Student"; }
}
} public static void m(Object x) {
//****************************
class GraduateStudent System.out.println(x.toString());
extends Student { }
} }

When the method m(Object x)is executed, the argument x’s toString method is
invoked. x may be an instance of GraduateStudent, Student, Person, or Object.
 Classes GraduateStudent, Student, Person, and Object have their own implementation
of the toString method. Which implementation is used will be determined dynamically
by the Java Virtual Machine at runtime.
This capability is known as dynamic binding. 66
Generic Programming
class Person { public class PolymorphismDemo {
public String toString() { public static void
return "Person"; main(String[] args) {
}
} m(new GraduateStudent());
//**************************** m(new Student());
class Student extends Person { m(new Person());
public String toString() { m(new Object());
return "Student"; }
}
} public static void m(Object x) {
//****************************
class GraduateStudent System.out.println(x.toString());
extends Student { }
} }

 Polymorphism allows methods to be used generically for a wide range of object


arguments. This is known as generic programming.
 If a method’s parameter type is a superclass (e.g., Object), you may pass an object to this
method of any of the parameter’s subclasses (e.g., Student or String).
 When an object (e.g., a Student object or a String object) is used in the method, the
particular implementation of the method of the object that is invoked (e.g., toString) is
determined dynamically. 67
Check Point
class Vehicle{
public void move(){
System.out.println(“Vehicles can move!!”);
}}

class MotorBike extends Vehicle{


public void move(){
System.out.println(“MotorBike can move and accelerate too!!”);
}
public void move2(){ //Code here}
}

class Test{
public static void main(String[] args){
Vehicle vh=new MotorBike();
vh.move(); // prints MotorBike can move and accelerate too!!
vh=new Vehicle();
vh.move(); // prints Vehicles can move!!

}} vh.move2(); // Error!!

68
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
m()
C1 o = new C1();
C2 o.m();
m()

C1
m()

69
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
m()
C1 o = new C1();
C2 o.m();
m()

C1

70
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
C1 o = new C1();
C2 o.m();

C1

71
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
C3 o = new C1();
C2 o.m();
m()

C1

72
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
m()
C3 o = new C2();
C2 o.m();
m()

C1
m()

73
Check Point
 Which m will be executed?
Cn
m()
Suppose :
C3
m()
C3 o = new C2();
C2 o.m();

C1
m()

74
Caution
 The JVM searches the
implementation for the method Cn
m()
m in C1, C2, ..., Cn-1 and Cn,
in this order, until it is found. C3
Once an implementation is m()

found, the search stops and the


C2
first-found implementation is m()
invoked.
C1
m()

75
Polymorphism Example
 Consider the following class hierarchy:

StaffMmeber

Volunteer Employee

Executive Hourly

76
StaffMember
#name: String
#address: String
#phone: String
+ StaffMember (…..)
+toString(): String
+pay(): double

Employee Volunteer
#socialSecNum: String
#payRate: double + Volunteer (…..)
+pay(): double
+ Employee (…..)
+toString(): String
+pay(): double

Executive Hourly

-bonus: double -hoursWorked: int


+ Executive (…..) + Hourly (…..)
+awardBonus (execBonus:double): void +toString(): String
+pay(): double +pay(): double
+addHour(moreHour: int):void
77
public class StaffMember
{
protected String name;
protected String address;
protected String phone;
//------------------------------------------------------------------------------------------
public StaffMember (String eName, String eAddress, String ePhone)
{
name = eName; address = eAddress; phone = ePhone;
}
//------------------------------------------------------------------------------------------
public String toString() {
String result = "Name: " + name + "\n";
result += "Address: " + address + "\n";
result += "Phone: " + phone;
return result;
}
//------------------------------------------------------------------------------------------
public double pay() {return 0;}
}

78
public class Volunteer extends StaffMember
{
public Volunteer (String eName, String eAddress, String ePhone)
{
super (eName, eAddress, ePhone);
}
//------------------------------------------------------------------------------------------
public double pay() { return 0.0; }
}

79
public class Employee extends StaffMember
{
protected String socialSecNum;
protected double payRate;
//------------------------------------------------------------------------------------------
public Employee (String eName, String eAddress, String ePhone, String
socSecNumber, double rate){
super (eName, eAddress, ePhone);
socialSecNum = socSecNumber;
payRate = rate;
}
//------------------------------------------------------------------------------------------
public String toString()
{
String result = super.toString();
result += "\nSocial Security Number: " + socialSecNum;
return result;
}
//------------------------------------------------------------------------------------------
public double pay() { return payRate; }
}

80
public class Executive extends Employee
{
private double bonus;
//------------------------------------------------------------------------------------------
public Executive (String eName, String eAddress, String ePhone, String
socSecNumber,
double rate) {
super (eName, eAddress, ePhone, socSecNumber, rate);
bonus = 0; // bonus has yet to be awarded
}
//------------------------------------------------------------------------------------------
public void awardBonus (double execBonus)
{ bonus = execBonus; }
//------------------------------------------------------------------------------------------
public double pay()
{ double payment = super.pay() + bonus;
bonus = 0;
return payment;
}
}

81
public class Hourly extends Employee
{
private int hoursWorked;
//------------------------------------------------------------------------------------------
public Hourly (String eName, String eAddress, String ePhone, String socSecNumber,
double rate) {
super (eName, eAddress, ePhone, socSecNumber, rate);
hoursWorked = 0;
}
//------------------------------------------------------------------------------------------
public void addHours (int moreHours) { hoursWorked += moreHours; }
//------------------------------------------------------------------------------------------
public double pay() {
double payment = payRate * hoursWorked;
hoursWorked = 0;
return payment;
}
//------------------------------------------------------------------------------------------
public String toString() {
String result = super.toString();
result += "\nCurrent hours: " + hoursWorked;
return result;
}
} 82
public class Staff {
public static void main (String[] args)
{
StaffMember[] staffList;
staffList = new StaffMember[6];
staffList[0] = new Executive ("Sam", "123 Main Line", "555-0469", "123-45-6789", 2423.07);
staffList[1] = new Employee ("Carla", "456 Off Line", "555-0101", "987-65-4321", 1246.15);
staffList[2] = new Employee ("Woody", "789 Off Rocker", "555-0000", "010-20-3040", 1169.23);
staffList[3] = new Hourly ("Diane", "678 Fifth Ave.", "555-0690", "958-47-3625", 10.55);
staffList[4] = new Volunteer ("Norm", "987 Suds Blvd.", "555-8374");
staffList[5] = new Volunteer ("Cliff", "321 Duds Lane", "555-7282");

double amount;
for (int count=0; count < staffList.length; count++)
{
System.out.println (staffList[count]);
amount = staffList[count].pay(); // polymorphic
if (amount == 0.0)
System.out.println ("Thanks!");
else
System.out.println ("Paid: " + amount);

}
}
}

83
Check Point
 In the previous program, is it legal to add the
following code to the main method?
a staffMember object is not nessarly an
Hourly or Executive object. StaffMember
class does not have addHours or
X (hour);
staffList[3].addHours addBouns methods.
((Hourly)staffList[3]).addHours (hour); Even though you can see that staffList[3]
is really an Hourly object, the compiler is
not so clever to know it.

X
staffList[0].awardBonus (bouns);
((Executive)staffList[0]).awardBonus (bouns);
To tell the compiler that staffList[3] is an
Hourly object, use an explicit casting.

84
Casting
 You have already used the casting operator to
convert variables of one primitive type to
another.
class Test {
public static void main(String args[]) {
double d;
int i;
d = 5; √
X
i = 3.5; √
}
} i = (int) 3.5;
– Widening is legal, while narrowing is illegal (unless
you cast) 85
Casting Objects
 Casting can also 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.
public static void m(Object x)
This statement is equivalent to:
Object o = new Student(); // Implicit casting
m(o);
The statement is known as implicit casting, is legal
because an instance of Student is automatically an
instance of Object.
86
Casting Objects
m(new Object());

public static void m(Student x) X


OR Compilation error
Student x = new Object();

Why does the statement Object x = new Student() work


and the statement Student x = new Object() doesn’t ????

This is because a Student object is always an instance of


Object, but an Object is not necessarily an instance of Student.

87
When Casting Is Necessary?
m(new Student());
public static void m(Object x) Object x = new student ();

Suppose you want to assign the object reference x to a variable of the


Student type using the following statement:
Student a= x;
X
Even though you can see that x is really a Student object, the
compiler is not so clever to know it.
What we do ?????????
use an explicit casting.

88
When Casting Is Necessary?
 To tell the compiler that o is a Student object, use an
explicit casting.
 The syntax is similar to the one used for casting among
primitive data types.
– Enclose the target object type in parentheses and place it
before the object to be cast, as follows:

Student a = (Student)x; // Explicit casting

89
Common Errors in Casting

90
Common Errors in Casting: solved

91
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.
– Consider the analogy of fruit, apple, and orange with the Fruit
class as the superclass for Apple and Orange.
Fruit fruit= new Apple();

Apple x = fruit; X a fruit is not necessarily an apple

Apple x = (Apple)fruit√ so you have to use explicit


casting to assign an instance of
Fruit to a variable of Apple
Orange x = (Orange)fruit;
X Exception 92
Caution
 In the StaffMember example, what happen if we try to
call addHours in for loop?

for (int count=0; count < staffList.length; count++){


((Hourly)staffList[count]).addHours (hour); X
}

We don’t know that staffList[3] is an Hour object , Or staffList[0] is


an Executive object
So what we do ???

Use the instanceof operator


93
The instanceof Operator
 Use the instanceof operator to test whether an
object is an instance of a class

for (int count=0; count < staffList.length; count++){


/** Perform casting if staffList[cont] is an
instance of Hourly*/
if (staffList[count] instanceof Hourly)
((Hourly)staffList[count]).addHours (hour);
}

94
Example: Polymorphism and Casting
 Creates two objects: a circle and a rectangle, then
invokes the displayObject method to display the
objects.
 The displayObject displays the diameter if the
object is a circle, and displays area if the object
is a rectangle.

95
public class CastingDemo {

public static void main(String[] args) {


// Create and initialize two objects
Object object1 = new Circle (1);
Object object2 = new Rectangle (1, 1);

// Display circle and rectangle


displayObject(object1);
displayObject(object2);
}

/** A method for displaying an object */


public static void displayObject(Object object) {
if (object instanceof Circle) {
System.out.println("The circle diameter is " + ((Circle)object).getDiameter());
}
else if (object instanceof Rectangle) {
System.out.println("The rectangle area is " + ((Rectangle)object).getArea());
}
}
}

96
Check Point
 What is the output of the following code? Shape
Square squr=new Square();
Shape shp=new Shape();
Square
if(squr instanceof Square)
System.out.println("squr is instance of Square class");
if(squr instanceof Shape)
System.out.println("squr is instance of Shape class");
if(shp instanceof Square)
System.out.println("shp is instance of Square class");
if(shp instanceof Shape)
System.out.println("shp is instance of Shape class")
Shp = new Square();
if(shp instanceof Square)
System.out.println("shp is instance of Square class");
if(shp instanceof Shape)
System.out.println("shp is instance of Shape class");
97
Equality
 Consider these two assignments:
Thing thing1 = new Thing();
Thing thing2 = new Thing();
Are these two “Things” equal?
– That’s up to the programmer!
 Consider:
Thing thing3 = new Thing();
Thing thing4 = thing3;
Are these two “Things” equal?
– Yes, because they are the same Thing!
98
== operand
 Primitives can always be tested for equality with
==
int x=9;
int y=9;
if (x==y)
 For objects, == tests whether the two are the
same object
 Because if test whether the to references are the same!

99
The equals()Method
 Objects can be compared with the method
equals(Object o) in java.lang.Object
Obj1.equals(Obj2);
What does do ????

 The equals() method compares the


contents of two objects. The default implementation of
the equals method in the Object class is as follows:

public boolean equals(Object obj) {


return this == obj;
}
100
The equals()Method
 Obj1 and Obj2 are Strings,
Obj1.equals(Obj2);
What does it do ????
– It is overridden in the class String

 Obj1 and Obj2 are arrays,


Obj1.equals(Obj2);
What does it do ????
– It is not overridden for arrays; == tests if its operands
are the same array

101
Check Point
 What is the output of the following code?
String s1="hi";
String s2="hi";
if(s1.equals(s2)) Equal
System.out.println("Equal");
else
System.out.println("Not equal");

Square sq1= new Square(30,"Yellow");


Square sq2= new Square(30,"Yellow");
if (sq1.equals(sq2)) Not
System.out.println("Equal"); Equal
else
System.out.println("Not equal");

102
Note
 Never use == to test equality of Strings or arrays
or other objects
 Use equals for Strings, and
java.util.Arrays.equals(a1, a2) for arrays
 If you test your own objects for equality,
override equals
– For example, the equals method is overridden in the
Circle class.
public boolean equals(Object o) {
if (o instanceof Circle)
return radius == ((Circle)o).radius;
else
return false;
} 103
Note
== equals

is used for comparing two is intended to test whether


primitive data type values or two objects have the same
for determining whether two contents, provided that the
objects have the same method is modified in the
references. defining class of the objects.

The == operator is stronger than the equals method, in that


the == operator checks whether the two reference variables
refer to the same object.

104
The finalize, clone, and getClass
Methods
 The finalize() method is invoked by the garbage
collector on an object when the object becomes garbage.
 The clone() method copies an object.
 The getClass() method returns an instance of the
java.lang.Class class, which contains the
information about the class for the object.
– Before an object is created, its defining class is loaded and the
JVM automatically creates an instance of
java.lang.Class for the class.
– From this instance, you can discover the information about the
class at runtime

105

You might also like