매개변수의 다형성
참조변수의 다형적인 특징은 매개변수에도 적용된다.
class Product {
int price;
int bonusPoint;
}
class Tv extends Product {}
class Computer extends Product {}
class Buyer { //Product를 구매하는 구매자
int money = 1000;
int bonusPoint = 0;
//물건을 구매하는 메서드
}
Buyer 클래스에 물건을 구입하는 기능의 메서드를 추가할 것.
Tv를 사는 경우, void buy(Tv t) { ... }
Computer를 사는 경우, void buy(Computer c) { ... }
이렇게 되면 제품의 종류가 늘어날 때마다 Buyer 클래스에는 새로운 buy 메서드를 추가해야 함.
메서드에 다형성을 적용하면 다음과 같이 하나의 메서드로 처리할 수 있다.
void buy(Product p) {
money -= p.price;
bonusPoint += p.bonusPoint;
}
매개변수가 Product 타입의 참조변수라는 것은.. 메서드의 매개변수로 Product 클래스의 자손 타입의 참조변수면 어느 것이나 매개변수로 받아들일 수 있다는 뜻이다.
또한, Product 클래스에 price와 bonusPoint가 선언되어 있기 때문에.. 참조변수 p를 통해 인스턴스의 price와 bonusPoint를 사용.
[다형성 장점]
1. 다형적 매개변수
2. 하나의 배열에 여러 종류 객체를 저장할 수 있다. (보통은 같은 타입만 저장됨)
1. 매개변수 다형성 예제
class Product{
int price;
int bonusPoint;
Product(int price){
this.price=price;
bonusPoint=(int)(price/10.0); //보너스포인트는 제품 가격의 10%
}
}
class Tv1 extends Product{
Tv1(){
super(100); //조상클래스의 생성자 소환
}
// Object 클래스의 toString() 오버라이딩.
// 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;
// 여기서 p가 의미하는 것은 p.toString임. p만 출력하면 자동으로 toString 출력되는데 위에서 오버라이딩 했으니 제품명이 뜨겠지.
System.out.println(p + " 을/를 구입하셨습니다.");
}
}
public class Ex7_8 {
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 + "점 입니다.");
}
}
2. 여러 종류의 객체를 배열로 다루기
조상타입의 참조변수로 자손타입의 객체를 참조하는 것이 가능하므로, Product 클래스가 Tv, Computer, Audio 클래스의 조상일 때 다음과 같이 할 수 있다.
Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
위 코드를 Product 타입의 참조변수 배열로 처리하면?
Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
조상타입의 참조변수 배열을 사용하면, 공통의 조상을 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있다.
또는 묶어서 다루고싶은 객체들의 상속관계를 따져서 가장 가까운 공통조상클래스 타입의 참조변수 배열을 생성해서 객체를 저장하면 됨.
class Product2{
int price;
int bonusPoint;
Product2(int price){
this.price=price;
bonusPoint=(int)(price/10.0); //보너스포인트는 제품 가격의 10%
}
}
class Tv2 extends Product2{
Tv2(){
super(100); //조상클래스의 생성자 소환
}
// Object 클래스의 toString() 오버라이딩.
// toString(): 객체가 가진 정보를 문자열로 나타내주는 메서드
public String toString() { return "TV"; }
}
class Computer2 extends Product2{
Computer2() { super(200); }
public String toString() { return "Computer"; }
}
class Audio2 extends Product2 {
Audio2() { super(50); }
public String toString() { return "Audio"; }
}
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; //제품명을 Product[] cart에 추가
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();
System.out.println("현재 남은 돈은 " + b.money +" 만원 입니다.");
System.out.println("현재 보너스 점수는 "+ b.bonusPoint + "점 입니다.");
}
}
위 코드에서는 Product2 배열로 구입한 제품들을 저장할 수 있도록 하며 배열의 크기를 10으로 지정했다.
11개 이상의 제품을 구매할 수 없게되는데, 이 때 배열의 크기를 무작정 크게 선언해도 손해다.
이런 경우 Vector 클래스를 사용한다.
내부적으로 Object 타입의 배열을 가지고 있어서, 배열에 객체를 추가하너가 제거할 수 있게 작성되어 있다.
또한 배열의 크기 알아서 관리해주기 떄문에.. 저장할 인스턴스 개수에 신경 안써도 됨.
Public class Vector extends AbstractList implements List, Cloneable, java.to.Serializable {
protected Object elementData[];
....
}
// Object[]: 최고 조상. 모든 종류의 객체 저장 가능하다. 배열의 크기 알아서 관리해준다.
// 배열의 단점: 한 번 만들면 크기가 변경 불가능. 그러니 Vector쓰자
'프로그래밍 > java' 카테고리의 다른 글
[JAVA] 인터페이스, 상속, 구현 (0) | 2022.08.31 |
---|---|
[JAVA] 추상 클래스와 추상 메서드 (abstract) (0) | 2022.08.31 |
[JAVA] 참조변수의 형변환 (0) | 2022.08.29 |
[JAVA] 다형성(polymorphism) (0) | 2022.08.28 |
[JAVA] 패키지와 import, 제어자, 겟터와 셋터 (0) | 2022.08.28 |