매개변수 다형성에 대해서 까먹어 정리해 보려고 한다.
본 포스팅은 JAVA의 정석 3판 - 저. 남궁 성 교재 ch7 - 5.5 매개변수의 다형성을 참고하였습니다.
참조변수의 다형적인 특징은 메서드의 매개변수에도 적용된다.
아래와 같이 클래스가 정의되어 있다고 가정하자.
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, Audio, Computer클래스의 조상이며, Buyer클래스는 제품(product)을 구입하는 사람을 클래스로 표현한 것이다.
Buyer클래스에 물건을 구입하는 기능의 메서드를 추가해보자.
구입할 대상이 필요하므로 매개변수로 구입할 제품을 넘겨받아야 한다.
Tv를 살 수 있도록 매개변수를 Tv타입으로 하였다.
void buy(Tv t){
// Buyer가 가진돈(money)에서 제품의 가격 (t.price)만큼 뺀다.
money -= t.price;
// Buyer의 보너스 점수(bonusPoint)에 제품의 보너스 점수(t.bounsPoint)를 더한다.
bonusPoint += t.bonusPoint;
}
But(Tv t)는 제품을 구입하면 제품을 구입한 사람이 가진 돈에서 제품의 가격을 빼고, 보너스 점수는 추가하는 작업을 하도록 작성하였다.
그런데 Buy(Tv t)로는 Tv밖에 구매할 수 없다.
그렇기 때문에 아래와 같이 다른 제품들도 구입할 수 있게 메서드가 추가로 필요하게 된다.
void buy(Tv t){
// Buyer가 가진돈(money)에서 제품의 가격 (t.price)만큼 뺀다.
money -= t.price;
// Buyer의 보너스 점수(bonusPoint)에 제품의 보너스 점수(t.bounsPoint)를 더한다.
bonusPoint += t.bonusPoint;
}
void buy(Computer c){
money -= c.price;
bonusPoint += c.bonusPoint;
}
void buy(Audio a){
money -= a.price;
bonusPoint += a.bonusPoint;
}
그런데 이렇게 하면 Product의 자식 클래스가 많아질수록(제품의 종류가 늘어나면) 새로운 buy메서드를 추가해야 한다.
제품 개수가 수만개면 buy메서드를 수만개 써야 한다...
메서드에 매개변수의 다형성을 적용하면 아래와 같이 하나의 메서드로 간단히 처리할 수 있다.
void buy(Product p){
money -= p.price;
bonusPoint += p.bonusPoint;
}
매개변수가 Product타입의 참조변수라는 것은, 메서드의 매개변수로 Product클래스의 자손타입의 참조변수면 어느 것이나 매개변수로 받아들일 수 있다는 뜻이다.
Product클래스에 price와 bounsPoint가 선언되어 있어 참조변수 p로 인스턴스의 price와 bounsPoint를 사용할 수 있어 위와 같은 코드 사용이 가능하다.
class Product{
int price;
int bonusPoint;
Product(int price){
this.price = price;
bonusPoint = (int)(price/10.0);
}
}
class Tv extends Product{
Tv(){ super(100);}
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 + "을 구입하셨습니다.");
}
}
public class PolyArgumentTest {
public static void main(String[] args) {
Buyer b = new Buyer();
b.buy(new Tv());
b.buy(new Computer());
System.out.println("현재 남은 돈은 "+b.money +"만원입니다.");
System.out.println("현재 남은 보너스 점수는 "+b.bonusPoint+"점 입니다.");
}
}
코드 출처: https://github.com/castello/javajungsuk3/blob/master/source/ch7/PolyArgumentTest.java
매개변수의 다형성의 또 다른 예를 들어 보자.
PrintStream 클래스에 정의되어 있는 print(Object obj)메서드를 보면
print(Object obj)는 매개변수로 Object타입의 변수가 선언되어 있다.
Object는 모든 클래스의 조상이므로 이 메서드의 매개변수로 어떤 타입의 인스턴스도 가능하므로,
이 하나의 메서드로 모든 타입의 인스턴스를 처리할 수 있다.
이 메서드는 매개변수에 toString()을 호출하여 문자열을 얻어서 출력한다. 실제 코드는 다음과 같다.
public void print(Obejct obj){
write(String.valueOf(obj));
}
public static String valueOf(Obejct onj){
return (obj == null) ? "null" : obj.toString();
}
'Language > Java' 카테고리의 다른 글
[Java] 제네릭(Generic) (0) | 2022.04.08 |
---|---|
[Java] 쓰레드의 상태 (0) | 2022.04.06 |
[Java] 쓰레드의 동기화 (0) | 2022.04.06 |
[Java] 쓰레드의 속성 (0) | 2022.04.05 |
[Java] 쓰레드, 멀티쓰레드 (0) | 2022.04.05 |