다형성 Polymorphism
자바에서 다형성이란 하나의 동작을 여러 방식으로 할 수 있게해주는 개념으로 정의하고있습니다.
Polymorphism(폴리모피즘)는 그리스어 poly와 morphs는 그리스어에서 파생되어 만들어진 단어입니다. poly는 다수를 의미하고 morphs는 형태를 의미합니다.
그래서 폴리모피즘의 뜻이 다형성이 되는거라고 하네요.(이하 polymorphism)
자바에는 두가지 타입의 polymorphism이 존재하는데, 컴파일타임 polymorphism과 런타임 polymorphism이 있습니다.
그리고 우리는 오버로딩과 오버로드를 통해 polymorphism을 구현할 수 있습니다!
만약 우리가 static method를 오버로드했다면 컴파일타임 polymorphism의 예입니다.
런타임 polymorphism의 예를 살펴봅시다.
1) Runtime Polymorphism in JAVA.
Runtime Polymorphism 혹은 Dynamic Method Dispatch 는
오러라이드된 메소드를 컴파일에서보다는 런타임에서 해결하는 프로세스입니다.
이 과정에서, 오버라이드된 메소드는 superClass의 변수 참조를 통해 호출됩니다.
메소드가 호출되는 결정은 참조 변수가 참조하는 객체에 기반합니다.
Upcasting(자동타입변환)
부모클래스 참조 변수가 자식 클래스 객체를 참조할 때 이를, 업 캐스팅! 이라고 합니다.
왜 갑자기 업캐스팅 얘기냐구요? 런타임 다형성을 이해하기위해서 필요하니까요!
런타입 다형성 얘제를 살펴볼게요.
class Bike{
void run(){System.out.println("running");}
}
class Splender extends Bike{
void run(){System.out.println("running safely with 60km");}
public static void main(String args[]){
Bike b = new Splender();
b.run();
}
}
output = running safely with 60km
Bike와 Splender라는 클래스를 만들고 Splender 클래스가 Bike를 상속했고 run()메소드를 오버라이드했습니다.
여기서 오버라이드된 run()메소드를 부모 클래스의 참조변수라고 부릅니다.
하위 클래스 객체를 참조하고 하위 클래스 메소드가 상위 클래스 메소드를 무시하므로
런타임에 하위 클래스 메소드가 호출됩니다.
은행 예를 들어볼까요?
package polymorphism;
class Bank{
float getRateOfInterest(){return 0;}
}
class SBI extends Bank{
float getRateOfInterest(){return 8.4f;}
}
class ICICI extends Bank{
float getRateOfInterest(){return 7.3f;}
}
class AXIS extends Bank{
float getRateOfInterest(){return 9.7f;}
}
class TestPolymorphism{
public static void main(String args[]){
Bank b;
b=new SBI();
System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());
b=new ICICI();
System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());
b=new AXIS();
System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());
}
}
output =
SBI Rate of Interest: 8.4
ICICI Rate of Interest: 7.3
AXIS Rate of Interest: 9.7
이자율을 가져오는 Bank라는 클래스가 있다고 가정합시다.
하지만 은행마다 이자율이 조금씨 다를수도 있습니다. (카뱅이 그리 좋다죠..?)
도형을 예로 들면 이렇게 됩니다.
package polymorphism;
class Shape{
void draw(){System.out.println("drawing...");}
}
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle...");}
}
class Circle extends Shape{
void draw(){System.out.println("drawing circle...");}
}
class Triangle extends Shape{
void draw(){System.out.println("drawing triangle...");}
}
class TestPolymorphism2{
public static void main(String args[]){
Shape s;
s=new Rectangle();
s.draw();
s=new Circle();
s.draw();
s=new Triangle();
s.draw();
}
}
output =
drawing rectangle...
drawing circle...
drawing triangle...
JAVA Runtime Polymorphism with DataMember
오버라이드된 메소드는 데이터멤버가 아닙니다. 그래서 런타임 다형성은 데이터 멤버로 만들어질 수 없습니다.
아래의 예제를 보면 두개의 클래스가 speedlimit이라는 데이터멤버를 가지고있고
자식객체를 참조하고있는 부모클래스 참조변수를 통해 데이터멤버에 접근해볼겁니다.
오버라이드되지않은 데이터멤버에 접근한다면, 부모클래스의 데이터멤버에 접근하게될겁니다.
왜냐면 재정의되지않았기 떄문에 순수호출이 되는거니까요.
package polymorphism;
class Bike{
int speedlimit=90;
}
class Honda3 extends Bike{
int speedlimit=150;
public static void main(String args[]){
Bike obj=new Honda3();
System.out.println(obj.speedlimit);
}
}
output = 90.
Java Runtime Polymorphism with Multilevel Inheritance.
다중레벨상속과 런타임 다형성에 대해서 간단하게 알아봅시다.
package polymorphism;
class Animal {
void eat() {
System.out.println("Animal: eating");
}
}
class Dog extends Animal {
void eat() {
System.out.println("Dog: eating fruits");
}
}
class BabyDog extends Dog {
void eat() {
System.out.println("BabyDog: drinking milk");
}
public static void main(String args[]) {
Animal a1, a2, a3;
a1 = new Animal();
a2 = new Dog();
a3 = new BabyDog();
a1.eat();
a2.eat();
a3.eat();
}
} output =
Animal: eating
Dog: eating fruits
BabyDog: drinking milk
감이 오시나요?
BabyDog이 Dog를 상속하고 Dog가 Animal을 상속합니다.
BabyDog이 가지고있는 오버라이드 메소드는 없기때문에 부모클래스의 eat()메소드를 가져옵니다.
RECENT COMMENT