다형성(Polymorphism)


🔎 다형성

다형성이란?

  • 여러 가지 형태를 가질 수 있는 능력.

  • 하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것.

즉, 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것이 다형성이다.

class Tv {
    boolean power;
    int channel;

    void method1() {}
}

class CaptionTv extends Tv {
    String text;

    void caption() {}
}
CaptionTv C = new CaptionTv();

// 조상클래스의 참조변수로 자손타입의 객체를 생성
Tv t = new CaptionTv();

반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.



🔎 참조 변수의 형변환

🔥 참조 변수의 형변환을 왜 할까? 🔥

참조변수(리모콘)을 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해

  • 서로 상속관계에 있는 타입간의 형변환만 가능하다.

  • 자손타입에서 조상타입으로 형변환 하는 경우, 형 변환 생략가능

class Car {
    String color;
    int door;

    void drive() {
        System.out.println("부릉부릉");
    }
}

class SportsCar {
    String price;

    void SportsMode() {
        Sytem.out.println("스포츠 모드 ON");
    }
}

public static void main(Strin[] args) {
    Car car = null;
    SportsCar sc = new SportsCar();
    SportsCar sc2 = null;

    sc.SportsMode();
    car = (Car)sc 
    /* 
    <자손 → 조상> 형변환
    (Car)생략 가능
    car.SportsMode(); 에러발생 
    */

    sc2 = (SprotsCar)car; // <조상 → 자손> 형변환
    sc2.SportsMode();
}


🔎 instanceof 연산자

🔥 참조 변수의 형변환을 왜 할까? 🔥

참조변수를 형변환하기 전에 가능여부를 확인할 때

  • 참조변수의 형변환 가능여부 확인에 사용. 가능하면 true를 반환한다.

  • 형변환 전에 반드시 instanceof 메서드로 확인해야 한다.

void myCar(Car c) {
    if (c instanceof SportsCar) {
        SportsCar sc = new SportsCar();
        sc.SportsMode();
    }
}


🔎 매개변수의 다형성

참조형 매개변수는 메서드 호출시,

자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.

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

	Product(int price) {
		this.price = price;
		bonusPoint = (int)(price/10.0);	// 보너스 점수는 제품가격의 10%
	}
}

/* Tv1 클래스 */
class Tv1 extends Product {
	Tv1() {
		// 조상클래스의 생성자 product(int price)를 호출한다  
		super(100);		// TV가격을 100만원으로 한다.
	}

	// Object클래스 toString()을 오버라이딩한다. 
	public String toString() { return "Tv"; }
}

/* Computer 클래스 */
class Computer extends Product {
	Computer() { super(200); }

	public String toString() { return "Computer"; }
}

/* Buyer 클래스 */
class Buyer {	            // 고객, 물건을 사는사람 
	int money = 1000;	    // 소유 금액 
	int bonusPoint = 0;     // 보너스 포인트 

    // buy 메서드의 매개변수로, Product타입의 참조변수 p 선언
	void buy(Product p) {
		if(money < p.price) {
			System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
			return;
		}

		money -= p.price;            //  - 구입한 가격 
		bonusPoint += p.bonusPoint;  //  + 보너스 포인트 
		System.out.println(p + "을 구입하셨습니다.");
	}
}

class Ex7_8 {
	public static void main(String args[]) {
		Buyer b = new Buyer();

		b.buy(new Tv1());		// buy(Product p)
		b.buy(new Computer());	// buy(Product p)

		System.out.println("현재 남은 돈은" + b.money + "만원입니다.");
		System.out.println("현재 보너스 점수는" + b.bonusPoint + "점입니다.");
	}
}