* JAVA - 다형성(polymorphism) (2) 예2번 틀림

참조변수와 인스턴스의 연결

멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우

  • 조상타입의 참조변수를 사용했을 때는 조상 클래스에 선언된 멤버변수가 사용되고
  • 자손타입의 참조변수를 사용했을 때는 자손 클래스에 선언된 멤버변수가 사용된다.

하지만 중복 정의되지 않은 경우

  • 조상타입의 참조변수를 사용했을 때와 자손타입의 참조변수를 사용했을 때의 차이는 없다.
  • 중복된 경우는 참조변수의 타입에 따라 달리지지만, 중복되지 않은 경우 하나뿐이므로 선택의 여지가 없기 때문이다.
class BindingaTest{
	public static void main(String[] args){
    	Parent p = new Child();
        Child c = new Child();
        
        System.out.println("p.x = " + p.x);
        p.method();
        System.out.println("c.x = " + c.x);
        c.method();
    }
}

class Parent{
	int x = 100;
    
    void method()
    {
    	System.out.println("Parent Method");
    }
}

class Child extends Parent{
	int x = 200;
    
    void method()
    {
    	System.out.println("Child Method");
    }
}

실행결과

p.x = 100
Child Method
c.x = 100
Child Method

타입은 다르지만, 참조변수 p와c 모두 Child인스턴스를 참조하고 있다. Parent클래스와 Child클래스는 서로 같은 멤버들을 정의하고 있다.

메서드인 method()의 경우 참조변수의 타입에 관계없이 항상 실제 인스턴스의 타입인 Child클래스에 정의된 메서드가 호출되지만, 인스턴스변수인 x는 참조변수의 타입에 따라서 달라진다.

class BindingaTest2{
	public static void main(String[] args){
    	Parent p = new Child();
        Child c = new Child();
        
        System.out.println("p.x = " + p.x);
        p.method();
        System.out.println("c.x = " + c.x);
        c.method();
    }
}

class Parent{
	int x = 100;
    
    void method()
    {
    	System.out.println("Parent Method");
    }
}

class Child extends Parent{}

실행결과

p.x = 100
Parent Method
c.x = 200
Parent Method
  • 이 처럼 자손 클래스에서 조상 클래스의 멤버를 중복으로 정의하지 않았을 때는 참조변수의 타입에 따른 변화는 없다.

  • 어느 클래스의 멤버가 호출되어야 할지, 즉 조상의 멤버가 호출되어야할 지, 자손의 멤버가 호출되어야 할지에 대한 선택의 여지가 없기 때문

  • 참조변수의 타입에 따라 결과가 달라지는 경우는 조상 클래스의 멤버변수와 같은 이름의 멤버변수를 자손 클래스에 중복해서 정의하 경우다.

class BindingaTest3{
	public static void main(String[] args){
    	Parent p = new Child();
        Child c = new Child();
        
        System.out.println("p.x = " + p.x);
        p.method();
        System.out.println("c.x = " + c.x);
        c.method();
    }
}

class Parent{
	int x = 100;
    
    void method()
    {
    	System.out.println("Parent Method");
    }
}

class Child extends Parent{
	int x = 200;
    
    void method()
    {
    	System.out.println("x = " + x);
        System.out.println("super.x =" + super.x);
        System.out.println("this.x =" + this.x);
    }
}

실행결과

p.x = 100
x=200
super.x = 100
this.x = 200

c.x = 200
x = 200
super.x = 100
this.x = 200

매개변수의 다형성

class Product{
	int price;			//제품 가격
    int bonusPoint;		//제품구매시 제공하는 보너스점수
}

class Tv 		extends 	Product{]
class Computer  extends  	Product[]
class Audio     extends 	Product[]

class Buyer{
	int money = 1000;	//소유금액
    int bonusPoint = 0;	//보너스점수
}
void buy(Tv t){
	//Buyer가 가진 돈 에서 제품의 가격(t.price)만큼 뺀다.
    money = money - t.price;
    
    //Buyer의 보너스점수에 제품의 보너스 점수를 더한다
   	bonusPoint = bonusPoint + t.bonusPoint;
}

위 메서드는 Tv밖에 살 수 없기 대문에 다른 제품들도 구입할 수 있는 메서드가 추가로 필요하다.

void buy(Computer c){
	//Buyer가 가진 돈 에서 제품의 가격(c.price)만큼 뺀다.
    money = money - c.price;
    
    //Buyer의 보너스점수에 제품의 보너스 점수를 더한다
   	bonusPoint = bonusPoint + c.bonusPoint;
}

void buy(Audio a){
	//Buyer가 가진 돈 에서 제품의 가격(a.price)만큼 뺀다.
    money = money - a.price;
    
    //Buyer의 보너스점수에 제품의 보너스 점수를 더한다
   	bonusPoint = bonusPoint + a.bonusPoint;
}

메서드의 매개변수에 다형성을 적용하면 아래와 같이 하나의 메서드로 간단히 처리할 수 있다.

	void buy(Product p){
    	money = money - p.money;
        bonusPoint = bonusPoint + p.bonusPoint;
    }

여러 종류의 객체를 배열로 다루기

Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();

이처럼 조상타입의 참조변수 배열을 사용하면, 공통의 조상을 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있다.

좋은 웹페이지 즐겨찾기