Polymorphism
SZABIST
Islamabad
Polymorphism
Pre-‐requisites
• Following
are
the
post
condi?ons
that
must
be
met
in
code
in
which
you
want
to
exploit
polymorphism:
– Inheritance
There
should
exist
a
hierarchy
where
some
classes
are
parent
of
the
child
classes
– Overriding
It
is
utmost
important
that
you
should
have
overridden
a
method
in
all
of
these
classes.
– It
is
for
this
method
you
will
observe
polymorphic
behavior.
Polymorphism:
Class
Diagram
Inheritance
Overriding
What
is
leI………..
1-‐-‐-‐-‐-‐-‐>Subsitu?on
Person
p
=
new
Student();
//
child
object
assigned
to
a
parent
type
2-‐-‐-‐-‐-‐-‐>
Method
Calling
p.toString();
//will
s?ll
call
student’s
toString()
Method
output
is
polymorhic
i.e.
even
though
the
object
reference
is
of
person
type,
it
has
the
capability
to
call
toString
of
all
its
child
classes.
Polymorphism 1
§ The is-a relationship between a superclass and a subclass has an
important implication. For example:
§ A cow is an animal
§ Therefore all cows are animals.
§ So you can substitute an object of the subclass Cow for an object of
the superclass Animal, because a cow is, after all, an animal.
§ For example, the following code is valid:
Animal a = new Animal(); // Variable a points to an object of Animal
a = new Cow(); // Now, a points to an object of Cow.
However, note that the reverse is not true: not all animals are cows.
Therefore, the following line of code is not valid:
Cow c = new Animal(); // not valid
Polymorphism 2
§ A superclass can have multiple subclasses
§ For example,
§ a cow is an animal
§ a buffalo is also an animal
§ This means you can substitute either a cow or a buffalo
for an animal
§ This is an example of polymorphism
§ Polymorphism means giving different meaning to the
same thing
§ Greek: poly = many, and morph = form
Polymorphism 3
1. public class TestPoly { 17. class Cow extends Animal {
2. public static void main(String [] 18. public void saySomething() {
args) { 19.// super.saySomething();
3. Animal heyAnimal = new Animal(); 20. System.out.println("Moo!");
4. Cow c = new Cow(); 21. }
5. Buffalo b = new Buffalo(); 22. }
6. heyAnimal=c;
7. heyAnimal.saySomething(); 23. class Buffalo extends Animal{
8. heyAnimal=b; 24. public void saySomething() {
9. heyAnimal.saySomething(); 25. // super.saySomething();
10. } 26. System.out.println("Bah!");
11.} 27. }
28. }
12.class Animal {
13. public void saySomething() {
14. System.out.println("Umm..."); The output from this code is:
15. }
16.} Moo!
Bah!
Polymorphism 4
§ Note that invoking two calls from the same object to the same method (lines
7 and 9), saySomething(), has different effects.
§ This is made possible by:
§ Assigning objects of different subclasses of Animal, cow and buffalo, to
the object reference of Animal,
§ And by having different implementations of the saySomething() method
in the subclasses (lines 18 and 24).
§ Note: The compiler only knows about the declared object reference types.
However, at runtime, the JVM knows what the referred object really is.
§ Note that the capability to convert an object reference from one type (Animal
in our example) to another type (say Cow) is at the heart of polymorphism.
§ This conversion can happen to both kinds of data types: primitives and
object
8
references.
Polymorphism 5
§ Polymorphism does not apply to the static class
members.
§ For example:
§ You have a static method with identical signatures
defined in the parent class and its subclass
§ You assign an instance of the subclass to the
reference variable of the parent class
§ The variable invokes this static method
§ In this case the parent version of the method will be
executed.
Conversion of Object Reference Types 1
§ An object reference is a variable that points (refers) to
the object (data),
§ A primitive variable holds the value (data) itself.
§ There are three kinds of object reference types:
§ A class
§ An interface
§ An array
§ Just like primitive types, object reference types can
also go through conversion in two ways:
§ Implicit conversion
§ Explicit conversion
Conversion of Object Reference Types 2
Assignment Conversion:
§ Implicit conversion of an object reference type in an
assignment operation typically looks like the following:
<sourceType> s = new <sourceType>();
<targetType> t = s; // Implicit conversion of <sourceType> to
<targetType>.
§ This is the general form of implicit conversion from
<sourceType> to <targetType> in assignment.
§ The <sourceType> and <targetType> may be a class, an
interface, or an array.
§ This creates nine possible cases for conversion.
Conversion of Object Reference Types 3
12
Conversion of Object Reference Types 4
§ A class type may be converted to another class type if one of the following is true:
§ The <sourceType> is a subclass of the <targetType>
§ The <sourceType> implements the <targetType>
§ An interface type may be converted to one of the following:
§ Another interface if the <sourceType> is a subinterface of the <targetType>
§ The Object type if the <targetType> is an object.
§ An array may be converted to one of the following:
§ Another array if the following conditions are true: both <sourceType> and <targetType> are
arrays of object reference types, and the object reference type of <sourceType> array
elements is convertible to the object reference types of <targetType> array elements.
§ The interface: Cloneable or Serializable.
§ The class Object.
Conversion of Object Reference Types 5
14
Conversion of Object Reference Types 6
§ As an example, consider the following lines of code:
Lab lab1 = new Lab();
ClassRoom csroom = lab1;
§ This code would work because the class Lab is being converted into
the class ClassRoom, and
Lab is a subclass of ClassRoom.
§ On the other hand, the following code will generate a compiler error:
ClassRoom croom = new ClassRoom();
Lab cslab = croom; // compiler error.
§ The compiler error will be generated because an attempt is being
made to convert ClassRoom
into Lab, but ClassRoom is not a subclass of Lab.
Conversion of Object Reference Types 7
§ Further, consider the following code:
1. LectureHall lh174 = new LectureHall();
2. Facilities facil174 = lh174;
3. LectureHall lh158 = facil174; // compiler error.
§ Line 2 will work because:
§ The class LectureHall is being converted into the interface Facilities
§ LectureHall extends ClassRoom
§ ClassRoom implements Facilities.
§ However, line 3 would generate a compiler error because
§ The interface Facilities is being converted into LectureHall
§ Facilities is not a subinterface of LectureHall.
Conversion of Object Reference Types 8
1. public class ObjectRefConversion{
2. public static void main(String[] args) {
3. ClassRoom[] crooms = new ClassRoom[10];
4. Room[] rooms;
5. Lab[] labs;
6. for (int i = 0; i<5; i++) {
7. crooms[i] = new ClassRoom();
8. }
9. rooms = crooms;
10. labs = crooms; // compiler error
11. } //end main
12. } //end class ObjectRefConversion
13.
16. class Room {
14. interface Facilities { 17. } .
15. }
18. class ClassRoom extends Room implements Facilities{
19. }
20. class Lab extends ClassRoom {
21. }
17
Conversion of Object Reference Types 9
§ The conversion in line 9 will work because:
§ rooms and crooms are both arrays
§ the element type of crooms (that is, ClassRoom) is convertible to
the element type of rooms (that is, Room).
§ On the other hand, line 10 will generate a compiler error because
§ the type of elements of array crooms (that is, ClassRoom) is not
convertible to the type of elements of array labs (that is, Lab).
18
Conversion of Object Reference Types 10
Method Call Conversion:
§ The rules for method call conversion are the
same as the rules for assignment conversion.
§ The point to remember here is that the
passed-in argument types are converted into
the method parameter types when the
conversion is valid.
Conversion of Object Reference Types 11
§ The general rule of thumb is that converting to a
superclass is permitted and converting to a subclass is
not permitted.
§ To see how the rules make sense in the context of
method calls, consider the extremely useful
java.lang.Vector class.
§ You can store anything you like in a vector (anything
nonprimitive,
that is) by calling the method add (Object ob).
§ For example, the following code stores a Tangelo in a
vector:
1. Vector myVec = new Vector();
2. Tangelo tange = new Tangelo();
3. myVec.add (tange);
Conversion of Object Reference Types 12
§ The tange argument will automatically be converted to type
Object.
§ The automatic conversion means that the people who wrote
the java.lang.Vector class didn’t have to write a separate
method for every possible type of object that anyone might
conceivably want to store in a vector.
§ This is fortunate: the Tangelo class was developed years
after the invention of the vector, so the developer of the
Vector class could not possibly have written specific
Tangelo-handling code.
§ An object of any class (and even an array of any type) can
be passed into the single add (Object ob) method.
Conversion of Object Reference Types 13
Explicit Conversion of Object Reference Types:
§ Explicit conversion of object reference types is also called
object reference casting.
§ The syntax is the same as that of primitive data type casting.
§ Any conversion that is allowed implicitly is also allowed
explicitly.
§ However, explicit conversion exhibits its real power when
we use it for conversions that are not allowed implicitly.
Conversion of Object Reference Types 14
§ To understand explicit conversion of object references, you must
understand that complete information may not be available at compile
time, unlike with the primitive types.
§ For example, consider the following lines of code:
Lab lab1 = new Lab();
ClassRoom csroom = lab1;
§ Here, csroom is an object reference of type ClassRoom.
§ This information is available at compile time.
§ However, it refers to the object lab1, which will be created at runtime.
§ Therefore, at compile time we do not know to which object type this
reference variable csroom refers.
Conversion of Object Reference Types 15
§ For Example:
Lab lab1;
if (cmdLineArg=1){
lab1 = new Lab();
}
else
{
lab1 = new SmallLab(); \\ if we assume a class SmallLab
}
ClassRoom csroom = lab1;
§ Again at compile time we do not know to which object type this
reference variable csroom refers
Conversion of Object Reference Types 16
§ Because object reference conversion may involve reference
types and object types, the rules of object reference casting
are much broader (than for primitives):
§ Some of the casting rules relate to the reference type
(which is known at compile time) and therefore can be
enforced at compile time.
§ Some of the casting rules relate to the object type
(which is not known at compile time) and therefore can
only be enforced at runtime
Conversion of Object Reference Types 17
§ At compile time, the following rules must be obeyed:
§ When both the source type and target type are classes, one
class must be a subclass of the other.
§ When both the source type and target type are arrays, the
elements of both the arrays must be object reference types
and not primitive types. Also, the object reference type of the
source array must be convertible to the object reference type
of the target array.
§ The casting between an interface and an object that is not
final is always allowed.
Conversion of Object Reference Types 18
As an example, consider the following code fragment:
1. Auditorium a1,a2;
2. ClassRoom c;
3. LectureHall lh;
4. a1 = new Auditorium();
5. c = a1; //legal implicit conversion.
6. a2 = (Auditorium) c; // Legal cast.
7. lh = (LectureHall) c; // Illegal
Conversion of Object Reference Types 19
§ Note that the code fragment has four object references, namely a1,
a2, c, and lh.
§ A single object is created and assigned to the reference a1 in line 4.
§ The assignment in line 5 represents a legal conversion because the
class of a1 is a subclass of the class of c.
§ In line 6, the compiler cannot determine the class of the object to
which c refers.
§ Therefore, line 6 would be fine at compile time because the
compiler would look at c as a ClassRoom, and Auditorium is a
subclass of ClassRoom.
§ Line 6 will also be fine at execution time because c already refers to
an object of Auditorium, and a2 is also of type Auditorium.
Conversion of Object Reference Types 18
§ In line 7, the compiler cannot determine the class of the object to which c
refers.
§ However, c is an abject reference of class ClassRoom, and LectureHall is a
subclass of ClassRoom. Therefore, line 7 will be fine at compile time.
§ However, at execution time, the JVM knows that c refers to an object of class
Auditorium (due to line 5).
§ Auditorium type cannot be converted to LectureHall.
§ Thus, the conversion in line 7 is illegal, and will generate an exception at
runtime.
§ For this to be legal, the class of the object to which c refers has to be either
LectureHall or a subclass of it.
§ When an attempt to cast a reference variable to a type is illegal, the JVM
throws the
ClassCastException