Title: ObjectOriented Programming: Polymorphism
1Object-Oriented ProgrammingPolymorphism
2Polymorphism
- Poly many
- Morph forms
- Polymorphism means many forms.
- In object-oriented programming, a method of a
superclass may be implemented in many different
ways by its subclasses. - Thus, a command may have many different forms.
3Polymorphism
- Polymorphism allows programs to similarly process
different objects of the same superclass. - Suppose for example a class animal has subclasses
of fish, frog, and bird. - The superclass defines a move method, but each
specific animal may move in a different way.
4Superclass defines move method
Animal
Fish
Frog
Bird
Each subclass implements move method in its own
way Programmer can send the move message to
each object without regard to which object it is.
5Polymorphism
- With polymorphism, we can program in a more
general way. - The main program can send a general message to
each object, and each object knows how it should
respond. - The program then becomes more easily extensible
to new objects that may not even be defined when
the program is written.
6Polymorphism
- The main program is simplified by working at a
higher level. - The main program can give a high level command,
and the details of the command are hidden inside
each object. - Since subclasses may implement different behavior
for the same command, treating a variety of
different objects in a similar way is made easier.
7Polymorphism
- The next example illustrates polymorphism.
- When the toString method is called, Java
performs dynamic binding (or late binding) which
determines the method to call at runtime by
examining which object is making the call, rather
than at compile-time by only considering the
reference type.
8- // Fig. 10.1 PolymorphismTest.java
- // Assigning superclass and subclass references
to superclass and subclass variables. - public class PolymorphismTest
-
- public static void main( String args )
-
- // assign superclass reference to
superclass variable - CommissionEmployee3 commissionEmployee
new CommissionEmployee3( - "Sue", "Jones", "222-22-2222", 10000,
.06 ) - // assign subclass reference to subclass
variable - BasePlusCommissionEmployee4
basePlusCommissionEmployee - new BasePlusCommissionEmployee4( "Bob",
"Lewis", "333-33-3333", 5000, .04, 300 )
- // invoke toString on superclass object
using superclass variable - System.out.printf( "s s\n\ns\n\n",
- "Call CommissionEmployee3's toString
with superclass reference ", - "to superclass object",
commissionEmployee.toString() )
Assign subclass variable to superclass variable
Actually uses subclass toString
9Abstract Classes
- An abstract class is one that cannot be
instantiated, but is only meant to serve as a
superclass. - A concrete class is one that can be instantiated.
- public abstract class Shape
-
-
10Abstract Methods
- An abstract class may contain one or more
abstract methods. - An abstract method does not provide an
implementation. - public abstract class Shape
-
- public abstract void draw()
-
11Abstract Classes
- A concrete subclass of an abstract class must
provide implementations for any abstract methods
in the superclass. - Constructors and static methods are never
abstract, since constructors are not inherited
and static methods cannot be overridden.
12Abstract Classes
- A variable of an abstract type can refer to an
object of a subclass of that type. - This permits polymorphism.
- Sometimes a collection, such as an array, of a
superclass or abstract superclass type contains
objects of subclasses. - An iterator is used to traverse all objects in
the collection. - A message sent to each object behaves in a
polymorphic manner.
13The next example uses this class hierarchy.
Italics indicate Employee is an abstract class.
Employee
Salaried Employee
Commission Employee
Hourly Employee
BasePlus Commission Employee
14- // Fig. 10.4 Employee.java. Employee abstract
superclass. - public abstract class Employee
-
- private String firstName
- private String lastName
- private String socialSecurityNumber
- // three-argument constructor
- public Employee( String first, String last,
String ssn ) -
- firstName first
- lastName last
- socialSecurityNumber ssn
- // end three-argument Employee constructor
- // set first name
- public void setFirstName( String first )
-
- firstName first
15- // set last name
- public void setLastName( String last )
-
- lastName last
- // end method setLastName
- // return last name
- public String getLastName()
-
- return lastName
- // end method getLastName
- // set social security number
- public void setSocialSecurityNumber( String
ssn ) -
- socialSecurityNumber ssn // should
validate - // end method setSocialSecurityNumber
- // return social security number
16- // return String representation of Employee
object - public String toString()
-
- return String.format( "s s\nsocial
security number s", - getFirstName(), getLastName(),
getSocialSecurityNumber() ) - // end method toString
- // abstract method overridden by subclasses
- public abstract double earnings() // no
implementation here - // end abstract class Employee
earnings() is an abstract method.
17- // Fig. 10.5 SalariedEmployee.java.
SalariedEmployee class extends Employee. - public class SalariedEmployee extends Employee
-
- private double weeklySalary
- // four-argument constructor
- public SalariedEmployee( String first, String
last, String ssn, - double salary )
-
- super( first, last, ssn ) // pass to
Employee constructor - setWeeklySalary( salary ) // validate and
store salary - // end four-argument SalariedEmployee
constructor - // set salary
- public void setWeeklySalary( double salary )
-
- weeklySalary salary lt 0.0 ? 0.0 salary
- // end method setWeeklySalary
18- // calculate earnings override abstract
method earnings in Employee - public double earnings()
-
- return getWeeklySalary()
- // end method earnings
- // return String representation of
SalariedEmployee object - public String toString()
-
- return String.format( "salaried employee
s\ns ,.2f", - super.toString(), "weekly salary",
getWeeklySalary() ) - // end method toString
- // end class SalariedEmployee
19- // Fig. 10.6 HourlyEmployee.java
- // HourlyEmployee class extends Employee.
- public class HourlyEmployee extends Employee
-
- private double wage // wage per hour
- private double hours // hours worked for week
- // five-argument constructor
- public HourlyEmployee( String first, String
last, String ssn, - double hourlyWage, double hoursWorked )
-
- super( first, last, ssn )
- setWage( hourlyWage ) // validate and
store hourly wage - setHours( hoursWorked ) // validate and
store hours worked - // end five-argument HourlyEmployee
constructor - // set wage
- public void setWage( double hourlyWage )
20- // return wage
- public double getWage()
-
- return wage
- // end method getWage
- // set hours worked
- public void setHours( double hoursWorked )
-
- hours ( ( hoursWorked gt 0.0 ) (
hoursWorked lt 168.0 ) ) ? - hoursWorked 0.0
- // end method setHours
- // return hours worked
- public double getHours()
-
- return hours
- // end method getHours
21- // calculate earnings override abstract
method earnings in Employee - public double earnings()
-
- if ( getHours() lt 40 ) // no overtime
- return getWage() getHours()
- else
- return 40 getWage() ( getHours() -
40 ) getWage() 1.5 - // end method earnings
- // return String representation of
HourlyEmployee object - public String toString()
-
- return String.format( "hourly employee
s\ns ,.2f s ,.2f", - super.toString(), "hourly wage",
getWage(), - "hours worked", getHours() )
- // end method toString
- // end class HourlyEmployee
22- // Fig. 10.7 CommissionEmployee.java.
CommissionEmployee class extends Employee. - public class CommissionEmployee extends Employee
-
- private double grossSales // gross weekly
sales - private double commissionRate // commission
percentage - // five-argument constructor
- public CommissionEmployee( String first,
String last, String ssn, - double sales, double rate )
-
- super( first, last, ssn )
- setGrossSales( sales )
- setCommissionRate( rate )
- // end five-argument CommissionEmployee
constructor - // set commission rate
- public void setCommissionRate( double rate )
-
23- // set gross sales amount
- public void setGrossSales( double sales )
-
- grossSales ( sales lt 0.0 ) ? 0.0 sales
- // end method setGrossSales
- // return gross sales amount
- public double getGrossSales()
-
- return grossSales
- // end method getGrossSales
- // calculate earnings override abstract
method earnings in Employee - public double earnings()
-
- return getCommissionRate()
getGrossSales() - // end method earnings
- // return String representation of
CommissionEmployee object
24- // Fig. 10.8 BasePlusCommissionEmployee.java
- // BasePlusCommissionEmployee class extends
CommissionEmployee. - public class BasePlusCommissionEmployee extends
CommissionEmployee -
- private double baseSalary // base salary per
week - // six-argument constructor
- public BasePlusCommissionEmployee( String
first, String last, - String ssn, double sales, double rate,
double salary ) -
- super( first, last, ssn, sales, rate )
- setBaseSalary( salary ) // validate and
store base salary - // end six-argument BasePlusCommissionEmploye
e constructor - // set base salary
- public void setBaseSalary( double salary )
-
- baseSalary ( salary lt 0.0 ) ? 0.0
salary // non-negative
25- // return base salary
- public double getBaseSalary()
-
- return baseSalary
- // end method getBaseSalary
- // calculate earnings override method
earnings in CommissionEmployee - public double earnings()
-
- return getBaseSalary() super.earnings()
- // end method earnings
- // return String representation of
BasePlusCommissionEmployee object - public String toString()
-
- return String.format( "s s s ,.2f",
- "base-salaried", super.toString(),
- "base salary", getBaseSalary() )
26instanceof
- If a superclass reference is used, it may refer
to objects of its subclasses. - If it is necessary to know which particular
subclass an object belongs to, the instanceof
operator can be used. - if ( currentEmployee instanceof
BasePlusCommissionEmployee ) -
-
-
27Downcasting
- If a superclass variable refers to a subclass
object, methods of the superclass can be called
which behave polymorphically (dynamic-binding). - However, attempting to call a subclass method
from a superclass reference results in a compile
error unless the superclass reference is downcast
to the subclass.
28Downcasting
- A subclass variable can be assigned to a
superclass variable since a subclass is-a
superclass. - However, assigning a superclass variable to a
subclass variable is a compile error without
casting. - Such casting is called downcasting since a
higher type is cast to a lower type. - superclass var subclass var // ok because of
is-a - subclass var superclass var // requires downcast
29getClass
- Class Object has a method getClass which
returns an object of type Class. - From this object, methods such as getName can
be called to get the class name of the object. - void printClassName(Object obj)
-
- System.out.println("The class of " obj "
is " obj.getClass().getName()) -
30- // Fig. 10.9 PayrollSystemTest.java
- // Employee hierarchy test program.
- public class PayrollSystemTest
-
- public static void main( String args )
-
- // create subclass objects
- SalariedEmployee salariedEmployee
- new SalariedEmployee( "John", "Smith",
"111-11-1111", 800.00 ) - HourlyEmployee hourlyEmployee
- new HourlyEmployee( "Karen", "Price",
"222-22-2222", 16.75, 40 ) - CommissionEmployee commissionEmployee
- new CommissionEmployee(
- "Sue", "Jones", "333-33-3333", 10000,
.06 ) - BasePlusCommissionEmployee
basePlusCommissionEmployee - new BasePlusCommissionEmployee(
- "Bob", "Lewis", "444-44-4444", 5000,
.04, 300 )
31- System.out.printf( "s\ns ,.2f\n\n",
- salariedEmployee, "earned",
salariedEmployee.earnings() ) - System.out.printf( "s\ns ,.2f\n\n",
- hourlyEmployee, "earned",
hourlyEmployee.earnings() ) - System.out.printf( "s\ns ,.2f\n\n",
- commissionEmployee, "earned",
commissionEmployee.earnings() ) - System.out.printf( "s\ns ,.2f\n\n",
- basePlusCommissionEmployee,
- "earned", basePlusCommissionEmployee.earn
ings() ) -
- // create four-element Employee array
- Employee employees new Employee 4
- // initialize array with Employees
- employees 0 salariedEmployee
- employees 1 hourlyEmployee
- employees 2 commissionEmployee
- employees 3 basePlusCommissionEmployee
32- // generically process each element in
array employees - for ( Employee currentEmployee employees
) -
- System.out.println( currentEmployee )
// invokes toString - // determine whether element is a
BasePlusCommissionEmployee - if ( currentEmployee instanceof
BasePlusCommissionEmployee ) -
- // downcast Employee reference to
- // BasePlusCommissionEmployee
reference - BasePlusCommissionEmployee employee
- ( BasePlusCommissionEmployee )
currentEmployee - double oldBaseSalary
employee.getBaseSalary() - employee.setBaseSalary( 1.10
oldBaseSalary ) - System.out.printf(
- "new base salary with 10
increase is ,.2f\n", - employee.getBaseSalary() )
- // end if
33Final
- If a method is declared final, it cannot be
overridden in a subclass. - All subclass calls to a final method would call
the superclass method. - Therefore, this binding can be done at compile
time rather than runtime. - This permits inlining to be performed by the
compiler for simple methods.
34Final
- If a class is declared final, it cannot be
subclassed. - One reason for doing this is for security
purposes. - For example, the String class in Java is final,
so that it cannot be subclassed such that its
security features are bypassed.
35Interfaces
- Sometimes different classes need common
functionality. - Such cases are supported by creating an
interface. - An interface specifies a set of methods to
support but does not provide implementation. - Interfaces only contain constants and abstract
methods.
36Interfaces
- All interface members are public.
- Methods are abstract.
- Constants are static and final.
- Generally, the keywords public, abstract, static
and final are not used in an interface
declaration since they will have these
characteristics by default.
37Interfaces
- To use an interface, a class implements the
interface. - Each interface method must be declared in the
(concrete) class that implements the interface
using the same signature. - Using interfaces lets very different objects
behave in a polymorphic way.
38Interfaces
- A class can inherit from only one direct
superclass, but it can implement multiple
interfaces. - public class MyClass extends MySuper implements
Int1, Int2, Int3, - An interface can be used when there is no
implementation to inherit. - If a class implements an interface but not all of
its methods, it must be an abstract class. - Interface methods are implicitly abstract.
- Interfaces are defined in their own .java file
named with the interface name.
39Interfaces
- When a class implements an interface, the is-a
relationship applies. - If Employee implements interface Payable, an
Employee is-a Payable. - Payable may be used as a type to refer to any
object that implements it. - This permits passing an object to a Payable
parameter, or setting a Payable reference to an
object.
40The next example uses this class hierarchy.
Italics indicate Employee is an abstract class.
ltltinterfacegtgt Payable
Invoice
Employee
Salaried Employee
41- // Fig. 10.11 Payable.java
- // Payable interface declaration.
- public interface Payable
-
- double getPaymentAmount() // calculate
payment no implementation - // end interface Payable
42- // Fig. 10.12 Invoice.java
- // Invoice class implements Payable.
- public class Invoice implements Payable
-
- private String partNumber
- private String partDescription
- private int quantity
- private double pricePerItem
- // four-argument constructor
- public Invoice( String part, String
description, int count, - double price )
-
- partNumber part
- partDescription description
- setQuantity( count ) // validate and store
quantity - setPricePerItem( price ) // validate and
store price per item - // end four-argument Invoice constructor
43- // get part number
- public String getPartNumber()
-
- return partNumber
- // end method getPartNumber
- // set description
- public void setPartDescription( String
description ) -
- partDescription description
- // end method setPartDescription
- // get description
- public String getPartDescription()
-
- return partDescription
- // end method getPartDescription
- // set quantity
44- // set price per item
- public void setPricePerItem( double price )
-
- pricePerItem ( price lt 0.0 ) ? 0.0
price // validate price - // end method setPricePerItem
- // get price per item
- public double getPricePerItem()
-
- return pricePerItem
- // end method getPricePerItem
- // return String representation of Invoice
object - public String toString()
-
- return String.format( "s \ns s (s)
\ns d \ns ,.2f", - "invoice", "part number",
getPartNumber(), getPartDescription(), - "quantity", getQuantity(), "price per
item", getPricePerItem() ) - // end method toString
45- // Fig. 10.13 Employee.java
- // Employee abstract superclass implements
Payable. - public abstract class Employee implements Payable
-
- private String firstName
- private String lastName
- private String socialSecurityNumber
- // three-argument constructor
- public Employee( String first, String last,
String ssn ) -
- firstName first
- lastName last
- socialSecurityNumber ssn
- // end three-argument Employee constructor
- // set first name
- public void setFirstName( String first )
46- // set last name
- public void setLastName( String last )
-
- lastName last
- // end method setLastName
- // return last name
- public String getLastName()
-
- return lastName
- // end method getLastName
- // set social security number
- public void setSocialSecurityNumber( String
ssn ) -
- socialSecurityNumber ssn // should
validate - // end method setSocialSecurityNumber
- // return social security number
47- // return String representation of Employee
object - public String toString()
-
- return String.format( "s s\nsocial
security number s", - getFirstName(), getLastName(),
getSocialSecurityNumber() ) - // end method toString
- // Note We do not implement Payable method
getPaymentAmount here so - // this class must be declared abstract to
avoid a compilation error. - // end abstract class Employee
48- // Fig. 10.14 SalariedEmployee.java
- // SalariedEmployee class extends Employee, which
implements Payable. - public class SalariedEmployee extends Employee
-
- private double weeklySalary
- // four-argument constructor
- public SalariedEmployee( String first, String
last, String ssn, - double salary )
-
- super( first, last, ssn ) // pass to
Employee constructor - setWeeklySalary( salary ) // validate and
store salary - // end four-argument SalariedEmployee
constructor - // set salary
- public void setWeeklySalary( double salary )
-
- weeklySalary salary lt 0.0 ? 0.0 salary
49- // return salary
- public double getWeeklySalary()
-
- return weeklySalary
- // end method getWeeklySalary
- // calculate earnings implement interface
Payable method that was - // abstract in superclass Employee
- public double getPaymentAmount()
-
- return getWeeklySalary()
- // end method getPaymentAmount
- // return String representation of
SalariedEmployee object - public String toString()
-
- return String.format( "salaried employee
s\ns ,.2f", - super.toString(), "weekly salary",
getWeeklySalary() ) - // end method toString
50- // Fig. 10.15 PayableInterfaceTest.java. Tests
interface Payable. - public class PayableInterfaceTest
-
- public static void main( String args )
-
- // create four-element Payable array
- Payable payableObjects new Payable 4
-
- // populate array with objects that
implement Payable - payableObjects 0 new Invoice( "01234",
"seat", 2, 375.00 ) - payableObjects 1 new Invoice( "56789",
"tire", 4, 79.95 ) - payableObjects 2 new SalariedEmployee(
"John", "Smith", "111-11-1111", 800.00 ) - payableObjects 3 new SalariedEmployee(
"Lisa", "Barnes", "888-88-8888", 1200.00 ) - System.out.println( "Invoices and Employees
processed polymorphically\n" ) - // generically process each element in
array payableObjects - for ( Payable currentPayable
payableObjects )
51Constants
- Sometimes constants are implemented using an
interface, although in Java 5.0 an enum is
preferred
- public interface Constants
-
- int ONE 1
- int TWO 2
- int THREE 3
- System.out.println(Constants.One)
- or if import static
- System.out.println(One)
52Common Interfaces
53End of Slides