Advanced Programming
SUT • Spring 2019
Polymorphism
Final Methods
You can send a talk request to an animal
What does it do?
It depends on type of the animal
The same note
Different sounds on different instruments
Common interface
The same request
Different behaviors
Depending on the type of object
The same interface
animal.talk()
instrument.play(int note)
But different implementation
in different classes
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
Shape s = new Rectangle();
Circle c = new Circle();
Shape s = c;
Upcasting is always valid
Down casting
Shape s = …
Circle c = s;
Circle c = (Circle) s;
Needs type cast
May cause errors
Shape s = new Rectangle();
s.draw();
double d = s.getArea();
Circle c = new Circle();
Shape s = c;
s.draw();
double d = s.getArea();
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();
}
}
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");
}
}
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();
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
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, …
Player[] players;
Refree[] refs;
Ball ball;
for (Player player: players){
player.draw();
}
for (Referee ref: refs){
ref.draw();
}
ball.draw();
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();
}
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");
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!";
}
}
public abstract class Animal {
private final String name;
protected Animal(String name){
this.name = name;
}
public String getName(){
return name;
}
public abstract String talk();
}
Animal[] animals = new Animals[]{
new Cat("Maloos"),
new Cat("Loos"),
new Dog("Fido")
};
for(Animal animal: animals){
System.out.println(animal.getName() + ": " + animal.talk());
}
Later!
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();
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;
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;
}
}
You can not inherit from final classes
No class can extend final classes
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
Final Methods
No override
Final Class
No sub-class
final keyword on data
Different from final classes & methods
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
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)");
}
}
Child child = new Child();
Parent parent = new Parent();
Parent parentRefToChild = new Child();
parent.f();
child.f();
parentRefToChild.f();
SomeClass square = new SomeClass();
square.method(parent);
square.method(child);
square.method(parentRefToChild);
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)");
}
}
SomeSubClass ref = new SomeSubClass();
ref.method(parent);
ref.method(child);
ref.method(parentRefToChild);
public boolean equals(Object obj) {…}
public boolean equals(Person obj) {…}