9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of...

48
1 SWEN221: Software Development 9: Polymorphism I David J. Pearce & Marco Servetto Computer Science, Victoria University

Transcript of 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of...

Page 1: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

1

SWEN221:Software Development

9: Polymorphism I

David J. Pearce & Marco ServettoComputer Science, Victoria University

Page 2: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

abstract class Equine {

private Point position;

public void run() {position.x+=1;}

abstract void draw();

}

class Horse extends Equine{

public void draw(){…}

}

class Zebra extends Equine{

public void draw(){…}

}

Equine

Horse Zebra

Superclass: Equine

Subclass: Horse, Zebra

Example class hierarchy

Page 3: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Mental Model of Typing

X

Horse

Horse(“fury”)

Object

Y

Equine

Static (or Declared)

type of y is “Equine”Dynamic (or Runtime) type of x and y is “Horse”

•Static Type:– Declared type of a variable

•Dynamic Type:– Type of object referred to by variable

– potentially different in different moments

abstract class Equine {...}

class Horse extends Equine{...}

class Zebra extends Equine{...}

Horse x=new Horse();

Equine y=x;

Page 4: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Inheritance / Subtype polymorphism

Horse and Zebra instances should be usable everywhere an instance of an Equine type is required.

A ColoredPoint instance should be usable everywhere an instance of Point Type is required.

Page 5: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Inheritance / Subtype polymorphism

More in general

Sublcasses instances should be usable everywhere a Supertype is required.

SHOULD means that YOU have to ensure this while writing the program.

Page 6: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

How YOU take care of this?

• Do not abuse instanceof and casts

• Understand and keep in mind the meaning of overriding a method

Page 7: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

class ManageEquine {

static float weightOfEquine(Equine q) {

if (q instanceof Horse) return 250f;

if (q instanceof Zebra) return 200f;

return 0f;

}

}

Page 8: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

class ManageEquine {

static float weightOfEquine(Equine q) {

if (q instanceof Horse) return 250f;

if (q instanceof Zebra) return 200f;

if (q instanceof Pegasus) return 310f;

throw new ThisIsNotHappeningError();

}

}

Page 9: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok,...

Page 10: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but,...

Page 11: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but, now, ...

Page 12: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but, now, it works, ...

Page 13: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but, now, it works, right?

Page 14: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but, now, it works, right? So what?

Page 15: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Someone can always add yet another subclass of Equine.

Ok, but, now, it works, right? So what?If in the future I add another subclass of Equine, I will add another “if” to that method.

Page 16: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Will you remember to do so?

Page 17: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Will you remember to do so?

Will you be still in charge to maintain such code?

Page 18: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s wrong with this?

Will you remember to do so?

Will you be still in charge to maintain such code?

And what if your code is a library and is the library user that adds the Equine subclass?

Page 19: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

What’s Really wrong with this?

It’s the mental setting that is profoundly wrong:

Inexpert programmers usually see the code just as a instrument to solve a concrete, contingent, problem.

Page 20: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

http://xkcd.com/844/

Page 21: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

The good mental setting

Write a (little?) set of libraries solving the category of problems in the problem domain.

The “real” program is just a little layer of code invoking (also) your libraries.

Page 22: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Wrong solution – if statement

class ManageEquine {

static float weightOfEquine(Equine q) {

if (q instanceof Horse) return 250f;

if (q instanceof Zebra) return 200f;

if (q instanceof Pegasus) return 310f;

throw new ThisIsNotHappeningError();

}

}

Page 23: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overriding

abstract class Equine {...

abstract float weight();

}

class Horse extends Equine{...

float weight(){return 200f;}

}

...

Page 24: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Page 25: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Page 26: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Equine x=new Horse()

x.weight()

Page 27: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Equine x=new Horse()

x.weight()

Page 28: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Equine x=new Horse()

x.weight()

class Horse{ ... float weight(){ return 200f;} ...

}

Page 29: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Equine x=new Horse()

x.weight()

class Horse{ ... float weight(){ return 200f;} ...

}

Page 30: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Good solution - Use overridingEquine x=....

x.weight()

Equine x=new Horse()

x.weight()

class Horse{ ... float weight(){ return 200f;} ...

}

Equine x=....

x.weight() --> 200f

Page 31: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Method dispatch

•Method dispatch:– Two phases – compile time and runtime

•Static checking phase (overloading resolution):– Based on static types of receiver and parameters– Only visible methods defined in the receiver static type

•Dynamic dispatch (overriding resolution):– Selection of method at runtime– Dynamic choice depends only on receiver

x.aMethod(y);

x is the receiver

y is the parameter

Page 32: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Dispatch 1: static checking● Identify static type of receiver● Find methods that could possibly apply● Correct name (also search in super-types)

● Visible

● Correct number of arguments

● Argument types that could apply

● By looking at Static types

● Take into account type conversions

● Choose the most specific method (overloading)

Page 33: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Dispatch 1: static checking

Method names and static types

Not return types

As result of this phase you have a

method descriptorThe method descriptor is chosen statically

Page 34: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Dispatch 1: static checking

What is a method descriptor?

As an example m(Foo,Bar,int)

● It is a methodName followed by the statically declared type of the parameters.

● Descriptors are the “overloaded resolved” version of a method name.

● If you have found m(Foo,Bar,int) as result of phase 1, it means that some class define a method m with Foo, Bar and int as parameter types.

Page 35: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Dispatch 2: dynamic dispatch

To determine which method is called at runtime:

a: Identify dynamic type of receiver

b: Check for the method implementation

using the method descriptorRemember, this used static types of arguments

If the method descriptor is not there, then look in super type(s) and then its super type(s) until match

Since the descriptor is from phase 1, you will find one match.

Page 36: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Method resolution

Big quiz day!!

Page 37: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

String whatAmI() {

return “I’m a Cat!”;

}

void print() {

System.out.println(whatAmI());

}}

class Kitten extends Cat {

String whatAmI() {

return “I’m a Kitten!”;

}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

gypsy.print();

spike.print();

“I’m a Kitten!”

“I’m a kitten!”A)

“I’m a Cat!”

“I’m a Kitten!”B)

“I’m a Cat!”

“I’m a Cat!”

C)

Page 38: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

String whatAmI() {

return “I’m a Cat!”;

}

void print() {

System.out.println(whatAmI());

}}

class Kitten extends Cat {

String whatAmI() {

return “I’m a Kitten!”;

}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

gypsy.print();

spike.print();

“I’m a Kitten!”

“I’m a kitten!”A)

“I’m a Cat!”

“I’m a Kitten!”B)

“I’m a Cat!”

“I’m a Cat!”

C)

Page 39: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

public void action(Cat c) {

System.out.println(1);}

public void action(Kitten c) {

System.out.println(2);}}

class Kitten extends Cat {}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(spike);

spike.action(teddy);

teddy.action(teddy);

1

2

2

A)

B)1

1

2

Page 40: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

public void action(Cat c) {

System.out.println(1);}

public void action(Kitten c) {

System.out.println(2);}}

class Kitten extends Cat {}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(spike);

spike.action(teddy);

teddy.action(teddy);

1

2

2

A)

B)1

1

2

Page 41: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quiz

1

2

2

A)

B)1

1

2

class Cat {

public void action(Cat c) {

System.out.println(1);}}

class Kitten extends Cat {

public void action (Kitten k) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(teddy);

spike.action(teddy);

teddy.action(teddy);

Page 42: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quiz

1

2

2

A)

B)1

1

2

class Cat {

public void action(Cat c) {

System.out.println(1);}}

class Kitten extends Cat {

public void action (Kitten k) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(teddy);

spike.action(teddy);

teddy.action(teddy);

Page 43: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quiz

1

1

2

A)

B)1

1

1

class Cat {

public void action(Kitten c) {

System.out.println(1);}}

class Kitten extends Cat {

public void action(Cat k) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(teddy);

spike.action(teddy);

teddy.action(teddy);

Page 44: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quiz

1

1

2

A)

B)1

1

1

class Cat {

public void action(Kitten c) {

System.out.println(1);}}

class Kitten extends Cat {

public void action(Cat k) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(teddy);

spike.action(teddy);

teddy.action(teddy);

Page 45: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

public void action(Cat c, Kitten k) {

System.out.println(1);}}

class Kitten extends Cat {

public void action(Kitten k, Cat c) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(spike,teddy);

spike.action(teddy,spike);

teddy.action(teddy,teddy);

1, 1, 2A)

C) 1, 2, 2

B) compilation error

Page 46: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Cat {

public void action(Cat c, Kitten k) {

System.out.println(1);}}

class Kitten extends Cat {

public void action(Kitten k, Cat c) {

System.out.println(2);}}

Cat gypsy = new Cat();

Cat spike = new Kitten();

Kitten teddy = new Kitten();

gypsy.action(spike,teddy);

spike.action(teddy,spike);

teddy.action(teddy,teddy);

1, 1, 2A)

C) 1, 2, 2

B) compilation error

Page 47: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Pow {

public int pow(int base,int exp) {

if(exp==0)return 1;

return base*pow(base,exp-1);

}}

class PowLog extends Pow {

public int pow(int base,int exp) {

System.out.println(“LogMessage”);

return super.pow(base,exp);}

}

System.out.println(new PowLog().pow(4,3));

LogMessage

64A)

B)

LogMessage

LogMessage

LogMessage

64

Page 48: 9: Polymorphism I•Static checking phase (overloading resolution): –Based on static types of receiver and parameters –Only visible methods defined in the receiver static type

SWEN221 Software Development

Quizclass Pow {

public int pow(int base,int exp) {

if(exp==0)return 1;

return base*pow(base,exp-1);

}}

class PowLog extends Pow {

public int pow(int base,int exp) {

System.out.println(“LogMessage”);

return super.pow(base,exp);}

}

System.out.println(new PowLog().pow(4,3));

LogMessage

64A)

B)

LogMessage

LogMessage

LogMessage

64