Polymorphism
Advanced Programming
SUT • Spring 2019
Outline
-
Polymorphism
-
Final Methods
Polymorphism
Animals can talk!
Talk request
-
You can send a talk request to an animal
-
What does it do?
-
It depends on type of the animal
Musical Instruments
-
The same note
-
Different sounds on different instruments
Polymorphic Behavior
-
Common interface
-
The same request
-
-
Different behaviors
-
Depending on the type of object
Polymorphism
-
The same interface
-
animal.talk()
-
instrument.play(int note)
-
-
But different implementation
-
in different classes
-
Polymorphism
-
Suppose Child is a subclass of Parent class.
-
Remember: A Child’s object is also a Parent’s object
-
is-a relationship
-
-
So these lines are valid:
-
Child c = new Child();
-
Parent p = new Parent();
-
p = c;
-
-
But this line is invalid:
-
c = p;
-
UpCasting
-
Upcasting
-
Shape s = new Rectangle();
-
Circle c = new Circle();
-
Shape s = c;
-
-
Upcasting is always valid
DownCasting
-
Down casting
-
Shape s = …
-
Circle c = s;
-
Circle c = (Circle) s;
-
Needs type cast
-
May cause errors
-
What About Method Calls?
-
Shape s = new Rectangle();
-
s.draw();
-
double d = s.getArea();
-
-
Circle c = new Circle();
-
Shape s = c;
-
s.draw();
-
double d = s.getArea();
-
Faculty & Employee
class Parent {
public void f() {
System.out.println("f() in Parent");
}
}
public class Child extends Parent {
public void f() {
System.out.println("f() in Child");
}
public static void main(String[] args) {
Parent p = new Parent();
p.f();
Child c = new Child();
c.f();
p = c;
p.f();
}
}
Compile-time Method Binding
-
Also known as Static Binding
-
When a method is called, compiler knows which method is called
-
The translation is done in compile-time
class SomeClass{
public void f() {
System.out.println("f");
}
public void g() {
f();
System.out.println("g");
}
}
Run-time Method Binding
-
Also known as Dynamic Binding
-
When you call a method on a superclass reference
-
Actual method is bound in runtime
-
(If it is overridden)
-
-
Performance overload
Parent p = new Parent();
p.f();
Child c = new Child();
c.f();
p = c;
p.f();
Virtual Methods
-
In some languages (like C++) you can specify the binding mechanism for methods
-
If a method is declared as virtual, dynamic binding is used for that method
Applications of Polymorphism
-
Polymorphic behavior
-
Suppose you have so many objects in a GUI application
-
All of them have draw() operation
-
You simply call draw() on every object
-
It knows how to draw itself
-
Classes : Drawable(superclass), Player, Referee, Ball, …
No Polymorphism
Player[] players;
Refree[] refs;
Ball ball;
for (Player player: players){
player.draw();
}
for (Referee ref: refs){
ref.draw();
}
ball.draw();
With Polymorphism
Player[] players;
Refree[] refs;
Ball ball;
for (Player player: players){
player.draw();
}
for (Referee ref: refs){
ref.draw();
}
ball.draw();
Drawable[] drawables;
for (Drawable drawable: drawables) {
drawable.draw();
}
Hint on Array Initialization
Cat maloos = new Cat("Maloos");
Cat loos = new Cat("Loos");
Dog fido = new Dog("Fido");
Animal[] animals = new Animals[]{maloos, loos, fido};
Animal[] animals = new Animals[3];
animals[0] = maloos;
animals[1] = loos;
animals[2] = fido;
Animal[] animals = new Animals[]{new Cat("Maloos"), new Cat("Loos"),
new Dog("Fido")};
Animal[] animals = new Animals[3];
animals[0] = new Cat("Maloos");
animals[1] = new Cat("Loos");
animals[2] = new Dog("Fido");
Sample
class Cat extends Animal {
public Cat(String name){
super(name);
}
public String talk(){
return "Meoww!!!";
}
}
class Dog extends Animal {
public Dog(String name) {
super(name);
}
public String talk(){
return "Hop! Hop!";
}
}
Animal Example
public abstract class Animal {
private final String name;
protected Animal(String name){
this.name = name;
}
public String getName(){
return name;
}
public abstract String talk();
}
Polymorphic Animals!
Animal[] animals = new Animals[]{
new Cat("Maloos"),
new Cat("Loos"),
new Dog("Fido")
};
for(Animal animal: animals){
System.out.println(animal.getName() + ": " + animal.talk());
}
More on Polymorphism
-
Later!
Final
Abstract Behaviors
-
You can not override final methods
-
final keyword
-
Static method binding for final methods
-
Private methods are implicitly final
-
Static methods are implicitly final
-
Static methods are statically bound
-
Invoked reference is not important
-
No polymorphism for static variables
-
final public void f();
Final Variables
-
You can define variables as final
-
The value of final variable will remain constant
-
You can not change the value of final variables
-
You should immediately assign a value to final variables
-
Final parameter
-
Final local variable
-
Final property
-
Final static variable
-
private final String name;
Final Variables
class SomeClass{
private final String name;
public final int val = 12;
void f(final int a) {
final int b = a + 1;
}
void g() {
final String s = "123";
}
protected SomeClass(String name) {
this.name = name;
}
}
Final Classes
-
You can not inherit from final classes
-
No class can extend final classes
Review of final Keyword
-
Final data
-
Const
-
Local variables
-
Method parameters
-
Member variables
-
Primitives = constant values
-
Objects = constant references
-
-
A compile-time constant that won’t ever change
-
A value initialized at run time that you don’t want changed
Review of final Keyword (2)
-
Final Methods
-
No override
-
-
Final Class
-
No sub-class
-
-
final keyword on data
-
Different from final classes & methods
-
Finalism and Performance
Final methods can be invoked inline
-
Compiler can bind final methods statically
Static binding
So it may bring a better performance…
-
It is now discouraged to use final to try to help the optimizer
Especially with Java 6+
-
Don’t worry about performance
Java optimizer
More on Polymorphism
Contents
class Parent{
public void f(){
System.out.println("f() in Parent");
}
}
class Child extends Parent{
public void f(){
System.out.println("f() in Child");
}
}
public class SomeClass {
public void method(Parent p){
System.out.println("method(Parent)");
}
public void method(Child p){
System.out.println("method(Child)");
}
}
What is the output of:
Child child = new Child();
Parent parent = new Parent();
Parent parentRefToChild = new Child();
parent.f();
child.f();
parentRefToChild.f();
- Output:
- f() in Parent
- f() in Child
- f() in Child
What is the output of:
SomeClass square = new SomeClass();
square.method(parent);
square.method(child);
square.method(parentRefToChild);
- Output:
- method(Parent)
- method(Child)
- method(Parent)
- Important Note:
- Polymorphic behavior for reference
- the reference before dot
- Not for the parameters
Note: Overloading
class SomeClass {
public void method(Parent p){
System.out.println("method(Parent)");
}
}
class SomeSubClass extends SomeClass{
public void method(Child p){
System.out.println("method(Child)");
}
}
-
method() is overloaded in SomeSubClass
- It is not overridden
- Two independent methods
What is the output of:
SomeSubClass ref = new SomeSubClass();
ref.method(parent);
ref.method(child);
ref.method(parentRefToChild);
- Output:
- method(Parent)
- method(Child)
- method(Parent)
A Question
- When we override equals() method
- Why do we pass Object as the parameter?
- For example class Person has an equals method like this:
- But not like this:
- Why?!
public boolean equals(Object obj) {…}
public boolean equals(Person obj) {…}
Title Text
Polymorphism
By Behnam Hatami
Polymorphism
Polymorphism / Advanced Programming Course @ SUT, Spring 2019
- 1,118