👩‍💻 BackEnd/☕️ 자바 [Java]

[Java] 자바의 정석 : 매개변수의 다형성

minhe2810 2024. 2. 26. 15:12

매개변수의 다형성 

1. 다형적 매개변수

2. 하나의 배열로 여러 종류 객체 다루기 

 

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

- 메서드의 매개변수를 조상 타입의 참조변수를 사용해서 하나의 메서드로 여러타입의 객체를 받을 수 있도록 

 

조상이 될 클래스 Product 생성 

class Product {
    int price;
    int bonusPoint;

    Product(int price) {
        this.price = price;
        bonusPoint = (int) (price / 10.0);  // 보너스 점수는 제품 가격의 10%
    }
}
  • int price 를 매개변수로 받는 생성자 작성
  • 보너스 점수는 제품 가격의 10%를 적립해주는 식 

 

Product를 상속받는 Tv, Computer 클래스 작성

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

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

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

    @Override
    public String toString() {
        return "Computer";
    }
}
  • super()로 조상 클래스의 생성자를 호출하여 가격을 설정한다. 
  • Object 클래스의 toString() 메서드를 오버라이드 해주고 리턴값을 String 클래스 이름으로 반환한다. 

 


 

추가적으로 고객 즉, 물건을 사는 사람에 대한 클래스를 생성한다. 

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

    void buy(Product p) {   // 부모타입이기 때문에 new Tv(), new Computer() 모두 들어올 수 있음.
        if (money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
        }
        money -= p.price;   // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint;   // 제품의 보너스 점수를 추가한다.
        System.out.println(p + "을/를 구입하셨습니다.");
    }
}
  • 소유 금액과 보너스 점수를 멤버 변수로 선언을 하고 
  • buy 메서드를 선언하여 Tv, Computer 두 클래스의 조상 클래스인 Product 타입을 매개변수로 받아온다.
    • 이로 인해 Tv, Computer 두가지 타입 모두 매개변수로 받아올 수 있게 된다. 
    • 이게 바로 다형성의 장점이다. 

 

 

메인 메서드에서 이를 호출

public class Ex7_8 {
    public static void main(String[] args) {
        Buyer b = new Buyer(); // 물건 사는 사람

        // 1번
        Product p = new Tv1();
        b.buy(p);

        // 2번 -> 1번 코드를 한 줄로 줄인 방식임.
//        b.buy(new Tv1()); -> 참조변수가 없기 때문에 해당 메서드에서 사용할 수 없다.
        b.buy(new Computer());

        System.out.println("현재 남은 돈은 " + b.money + "만원 입니다. ");
        System.out.println("현재 보너스 점수는 " + b.bonusPoint + "점입니다.");
    }
  • Buyer 객체를 생성한 뒤 buy() 메서드를 사용하여 구매할 상품의 객체를 매개변수로 전달한다.
  • 타입이 다르지만 buy 메서드는 이 둘의 부모 클래스 타입으로 매개변수를 받아오므로 하나의 메서드로 다른 타입의 클래스를 받아오는 것이 가능해진다. 

출력내용


 

2. 하나의 배열에 여러 종류 객체 저장 

- 조상타입의 배열에 자손들의 객체를 담을 수 있다.  

- 하나의 배열에 여러 종류 객체 저장  (다형성을 이용하여 생긴 장점) 

 

조상 클래스 Product2 생성

class Product2 {
    int price;
    int bonusPoint;

    Product2(int price) {
        this.price = price;
        bonusPoint = (int) (price / 10.0);
    }

    Product2() {
        // 기본 생성자
    }
}

 


 

Product2 클래스를 상속 받을 자손 클래스 생성


class Tv2 extends Product2 {
    Tv2() {
        super(100);
    }

    @Override
    public String toString() {
        return "TV";
    }
}

class Computer2 extends Product2 {
    Computer2() {
        super(200);
    }

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

}

class Audio2 extends Product2 {
    Audio2() {
        super(50);
    }

    @Override
    public String toString() {
        return "Audio";
    }
}
  • 마찬가지로 toString() 메서드 재정의 

 

buyer 클래스 생성 및 메서드 추가


class Buyer2 {
    int money = 1000;
    int bonusPoint = 0;

    Product2[] cart = new Product2[10];
    int i = 0;

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

        money -= p.price;
        bonusPoint += p.bonusPoint;
        cart[i++] = p;
        System.out.println(p + "을/를 구입하셨습니다. ");
    }

    void summary() {
        int sum = 0;
        String itemList = "";

        for (int i = 0; i < cart.length; i++) {
            if (cart[i] == null) break;
            sum += cart[i].price;
            itemList += cart[i] + " , ";
        }
        System.out.println("구입하신 물품의 총금액은 " + sum + "만원입니다.");
        System.out.println("구입하신 제품은 " + itemList + "입니다.");
    }
}

 

메인 메서드에서 호출

public class Ex7_9 {

    public static void main(String[] args) {
        Buyer2 b = new Buyer2();

        b.buy(new Tv2());
        b.buy(new Computer2());
        b.buy(new Audio2());

        b.summary();
    }
}

 

출력 내용