101
PL in Java Week04 Polymorphism 조영호 [email protected]

[NHN NEXT] Java 강의 - Week4

Embed Size (px)

Citation preview

PL in Java Week04

Polymorphism

조영호 [email protected]

지난 주에…

사람과 킬러

일반화와 특수화 일반화 특수화

일반화와 특수화 일반화 특수화

설명은 더 추상적이고

집합의 크기는 더 크고

일반화와 특수화 일반화 특수화

설명은 더 구체적이고

집합의 크기는 더 작고

일반화와 특수화 일반화 특수화

특수화 집합은 일반화 집합의 부분집합

사람 킬러 더 일반적인 개념

더 특수한 개념

class Person { String name; int age; String introduce() { } }

Person & Killer

class Killer extends Person { String warning; String weapon; String getWeapon() { } }

일반화

특수화

is-a Relationship

Killer is-a Person

Person Killer Class

Class

new Killer()

new Killer()

new Killer()

new Person()

new Person()

new Person()

new Person()

new Person()

new Person()

new Person()

new Person()

new Person()

new Person()

name = 요츠바 age = 5

warning = You..

weapon = 총

Person

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

yotsuba

Killer

this

class Person { String name; int age; ... String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

Person yotsuba = new Person("요츠바", 5);

name = 요츠바 age = 5

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

Method Lookup

this에서 시작

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

name = 요츠바 age = 5

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

yotsuba.introduce()

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

name = 요츠바 age = 5

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

yotsuba.toString()

class Killer extends Person { }

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

name = 요츠바 age = 5

warning = You..

weapon = 총

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

class Killer

superclass

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

name = 요츠바 age = 5

warning = You..

weapon = 총

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

class Killer

superclass

yotsuba.introduce()

class Killer extends Person { }

class Object

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

name = 요츠바 age = 5

warning = You..

weapon = 총

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

class Killer

superclass

yotsuba.introduce()

String introduce() { return "무기 : " + weapon + "," + "이름 : " + name + ", 나이 " + age + "세"; }

class Killer extends Person { String introduce() { return "무기 : " + weapon + "," + "이름 : " + name + ", 나이 " + age + "세"; } }

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

class Object

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

class Person { } class Killer extends Person { }

Person

Killer

UML

Person

Killer

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

Parent <= Child

Person

Killer

Parent <= Child

UpCasting

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

Person

Killer

Child <= Parent

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); Killer killerYotsuba = yotsuba;

Person

Killer

Child <= Parent

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); Killer killerYotsuba = yotsuba;

Compile Error!

Person

Killer

Child <= Parent

DownCasting

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); Killer killerYotsuba = yotsuba;

Person

Killer

Child <= (Child)Parent

DownCasting

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); Killer killerYotsuba = (Killer)yotsuba;

Person

Killer

Killer yotsuba = (Killer)new Person("요츠바", 5);

Compile Success

Person

Killer

Killer yotsuba = (Killer)new Person("요츠바", 5);

Runtime Exception

ClassCastException

Compile Time

Runtime

vs

Compile Time Person yotsuba = ... Killer killeryotsuba = ...

Person yotsuba = killeryotsuba; Killer killeryotsuba = (Killer)yotsuba;

실제 생성된 객체 타입이 무엇이건 상관없이

참조 변수의 타입만을 이용해 업/다운 캐스팅

Runtime Person yotsuba = new Person("요츠바", 5);

Killer killeryotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

Killer killeryotsuba = (Killer)yotsuba;

실제 생성된 객체 타입을 이용해

업/다운 캐스팅

ClassCastException

Runtime - instanceof

instanceof DownCast

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); if (yotsuba instanceof Killer) { Killer killerYotsuba = (Killer)yotsuba; killerYotsuba.getWeapon(); }

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

Polymorphism

many forms

서로 다른 타입

서로 다른 행동

같은 메시지

Person yotsuba = ... yotsuba.introduce();

Person yotsuba = new Person("요츠바", 5); yotsuba.introduce();

이름 : 요츠바, 나이 5세

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총"); yotsuba.introduce();

무기 : 총, 이름 : 요츠바, 나이 5세

UpCasting

Person = Person

Person = Killer

this

Method Lookup

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

name = 요츠바 age = 5

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

yotsuba.introduce()

Person yotsuba = new Person("요츠바", 5);

name = 요츠바 age = 5

warning = You..

weapon = 총

this

class Person String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; }

class

class Object

superclass

String toString() { ... }

class Killer

superclass yotsuba.introduce()

class Killer extends Person { String introduce() { return "무기 : " + weapon + "," + "이름 : " + name + ", 나이 " + age + "세"; } }

class Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

String introduce() { return "무기 : " + weapon + "," + "이름 : " + name + ", 나이 " + age + "세"; }

Runtime Binding

or

Dynamic Binding

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

Person yotsuba = new Killer("요츠바", 5, "You can tell me in hell.", "총");

이게 가능하다면

void method(Person person) { ... }

이것도 가능합니다

method(new Killer("요츠바", 5, "You can tell me in hell.", "총"));

IronMan Person

class IronMan { Person person; IronMan(Person person) { this.person = person; } }

생성자도 일종의 메소드

IronMan ironMan = new IronMan(new Person("토니 스타크", 40)); IronMan ironYotsuba = new IronMan(new Killer("요츠바", 5, "You can tell me in hell.", "총"));

public class IronMan { Person person; IronMan(Person person) { this.person = person; } String introduce() { return person.introduce(); } }

Polymorphism

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

역할, 책임, 협력

시체를 검시해 주게

사건을 수사해 주세요

경감

탐정 조수

역할

책임

협력

public class IronMan { Person person; IronMan(Person person) { this.person = person; } String introduce() { return person.introduce(); } }

IronMan.introduce()

introduce introduce

Collaboration

IronMan Person

introduce introduce

Responsibility

IronMan Person

IronMan Person introduce introduce

Role

IronMan Person introduce introduce

Introduce라는 메시지를 수신하고

처리할 수만 있다면

introduce

IronMan introduce introduce

모두 다 Person 역할을 수행할 수 있다고

볼 수 있습니다.

Person

IronMan introduce introduce

다형성은 동일한 역할을 수행하는 객체들이

동일한 메시지에 대해

서로 다른 방식으로 반응하는 것을 의미

Person

IronMan introduce introduce

Person

in OO Paradigm

Generalization

IronMan introduce introduce

Person

in Class-Based OOPL

Inheritance

Person Role

class Person { } class Killer extends Person { } class Musician extends Person { }

Person

Killer Musician

IronMan introduce introduce

모두 다 Person 역할을 수행할 수 있다는 것은

Person

IronMan introduce introduce

Person 대신 사용될 수 있다는 것을 의미합니다

Person

UpCasting

class Person { } class Killer extends Person { } class Musician extends Person { }

Person

Killer Musician

IronMan은 미래에 등장할 Person의

서브 클래스와도 협력이 가능

Person

Killer Musician

IronMan

Flexible

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

IronMan introduce introduce

Person

IronMan의 입장에서는

IronMan introduce introduce

Person 대신 사용되는 객체들이 introduce

메시지를 이해할 수만 있으면 됩니다.

Person

IronMan introduce introduce

Introduce에 대한 메소드가 실제로 어떻게

구현되어 있는지는 상관이 없습니다.

Person

class Person { String name; int age; String introduce() { } }

introduce()의 시그니처만 알면 되죠

class Person { String name; int age; abstract String introduce(); }

Abstract Method

Child Class는 반드시 Abstract Method를 Override 해야 합니다

abstract class Person { String name; int age; abstract String introduce(); }

Abstract Class

Abstract Method를 가진 Class는

Abstract Class로 선언되어야 합니다.

abstract class Person { String name; int age; abstract String introduce(); }

Abstract Class

Abstract Class는 new를 이용해 인스턴스를 생성할 수 없습니다.

class Kid extends Person { String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

Kid class

class Killer extends Person {

String introduce() { return "무기 : " + weapon + ", " + "이름 : " + name + ", 나이 " + age + "세"; } }

Killer class

class Musician extends Person {

String introduce() { return "악기 : " + instrument + ", " + "이름 : " + name + ", 나이 " + age + "세"; } }

Musician class

abstract class Person { String name; int age; abstract String introduce(); }

Specification

IronMan과 협력하려면 introduce를 구현해야 한다

abstract class Person { String name; int age; abstract String introduce(); }

Remove Code Duplication

Person 역할을 하는 모든 객체들은 name과 age를 가져야 한다

To p i c s

UpCasting

Polymorphism

Polymorphic Arguments

Role

Abstract Class

Interface

IronMan introduce introduce

Person

Iron과 함께 협력하는 클래스들은

IronMan introduce introduce

Person

IronMan과 함께 협력하는 클래스들은

Person의 서브 클래스들로 한정

Person

Killer Musician

IronMan

만약 IronMan 안에 펭귄을 넣고 싶다면?

Person 상속 계층에 속하지 않은 객체와도

협력해야 합니다.

Person

Killer Musician

IronMan

Penguin

Animal

class Person { } class Killer extends Person { }

Person

Killer

Java - Single Inheritance

Multiple Inheritance

Person

Killer Musician

IronMan

Penguin

Animal

Animal is-a Person???

Person

Killer Musician

IronMan

Penguin

Animal

Interface

interface Tellable { String introduce(); }

메소드 구현이 없습니다

모든 메소드가 abstract method

public abstract class Person implements Tellable { ... }

Person implements Tellable

public class Kid extends Person { public String introduce() { return "이름 : " + name + ", 나이 " + age + "세"; } }

인터페이스에서 받은 메소드는 public으로

public abstract class Animal implements Tellable { ... }

Animal implements Tellable

public class IronMan { Tellable tellable; IronMan(Tellable tellable) { this.tellable = tellable; } String introduce() { return tellable.introduce(); } }

IronMan – Tellable Interface

Person

Killer Musician

IronMan

Penguin

Animal

<<interface>>

Tellable

More Flexible

클래스 계층 구조에 독립적