8월 18일(TIL), 항해 5일차

코코·2023년 8월 19일
0

TIL(Today I Learned)

목록 보기
7/19
post-thumbnail

매개변수의 다형성

참조형 매개변수는 메서드 호출 시, 자신과 같은 타입 또는 자손 타입의 인스턴스를 넘겨줄 수 있다.

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;	// 보너스점수
}

다음과 같은 상황을 가정해보자. Product란 클래스가 있고, 이 클래스를 상속받는 Tv, Computer, Audio 클래스가 있다 이들은 부모 - 자식 관계다. 그리고 별도로 물건 사는 사람을 표현한 Buyer란 클래스를 만들어주었다.

void buy(Tv t) {
	money -= t.price;
    bonusPoint += t.bonusPoint;
}

Buyer라는 사람이 물건을 살 수 있게 buy라는 메서드를 추가해주었다. buy메서드의 매개변수를 Tv로 해놨기 때문에 오직 Tv만 들어올 수 있다.
만약 다른 Computer나 Audio가 매개변수로 들어오는 메서드가 필요하다면

void buy(Computer c) {
	money -= c.price;
    bonusPoint += a.bonusPoint;
}
void buy(Computer c) {
	money -= c.price;
    bonusPoint += a.bonusPoint;
}

다음과 같이 동일한 이름과 동일한 동작을 하는 메서드를 더 생성해야 한다. (참고로 이렇게 동일한 메서드명이지만 매개변수의 갯수나 타입이 다른 경우를 '오버로딩(Overloading)' 이라고 한다.) 이렇게 되면 코드 중복이 발생하고 관리도 힘들어진다.

이런 경우를 방지하기 위해,

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

이까의 Tv 매개변수가 들어간 buy() 메서드를 위와 같이 변경해주었다.

// 위에서 본것과 같이 Product는 부모, 
// Tv와 Computer,Audio는 자식이기 때문에 
// 이와 같이 객체 생성이 가능하다.

Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
Buyer b = new Buyer();

Tv tv = new Tv();
Computer com = new Computer();

b.buy(tv);
b.buy(com);

이렇게 되면 굳이 buy() 메서드를 여러개 만들지 않고도 조상 타입의 변수로 자손 타입의 객체를 가르킬 수 있다. 이것이 다형성이고 다형적 매개변수의 장점이다.

밑에 있는 예제를 통해 직접 체험해보자.

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

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



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

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



class Computer extends Product {
    Computer() { super(200); }

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



class Buyer {               // 고객, 물건을 사는 사람
    int money = 1000;       //소유금액
    int bonusPoint = 0;     // 보너스점수

    void buy(Product p) {
        if(money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
            return;
        }

        money -= p.price;                   // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint;         // 제품의 보너스 점수를 추가한다.
        System.out.println(p + "을/를 구입하셨습니다.");
     // System.out.println(p.toString() + "을/를 구입하셨습니다.");       
     // 위의 두 코드는 같은 코드다. toString() 은 생략 가능하기 때문
     
    }
}


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

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

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

0개의 댓글