👩💻 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();
}
}
출력 내용