반응형
앞서 배웠던 묵시적 클래스 형 변환과 가상 메서드를 바탕으로 다형성을 이해할 수 있다.
- 다형성이란?
하나의 코드가 여러 자료형으로 구현되어 실행하는 것
- 다형성 코드 예시
package first_project;
class Animal{
public void move() {
System.out.println("animal moves.");
}
}
class Human extends Animal{
public void move() {
System.out.println("A man walks.");
}
}
class Tiger extends Animal{
public void move() {
System.out.println("A tiger runs.");
}
}
class Eagle extends Animal{
public void move() {
System.out.println("An eagle flies.");
}
}
public class AnimalTest {
public void moveAnimal(Animal animal) { //매개변수의 자료형이 상위 클래스
animal.move();
}
public static void main(String[] args) {
AnimalTest atest = new AnimalTest();
atest.moveAnimal(new Human());
atest.moveAnimal(new Tiger());
atest.moveAnimal(new Eagle());
}
}
결과
A man walks.
A tiger runs.
An eagle flies.
위에서 moveAnimal() 메서드는 어떠한 인스턴스가 넘어와도 모두 Animal형으로 변환함.
따라서 Animal에서 정의한 move()메서드를 호출할 수 있는데 가상 메서드 원리에 의하여
Animal의 move() 메서드가 아닌 실제 인스턴스의 메서드가 각각 호출됨
- 다형성의 장점
프로그램의 확장성, 유지 보수 편리
- Customer 클래스와 VIPCustomer 클래스에 다형성 활용
package first_project;
public class Customer {
protected int customerId;
protected String customerName;
protected String customerGrade;
int bonusPoint;
double bonusRatio;
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerGrade() {
return customerGrade;
}
public void setCustomerGrade(String customerGrade) {
this.customerGrade = customerGrade;
}
public Customer() {
initCustomer();
}
public Customer(int customerId, String customerName) {
this.customerId = customerId;
this.customerName = customerName;
initCustomer();
}
private void initCustomer() {
customerGrade = "Silver";
bonusRatio = 0.01;
}
public int calcPrice(int price) {
bonusPoint += price* bonusRatio;
return price;
}
public String showCustomerInfo() {
return customerName+ "님의 등급은 "+customerGrade+"이며, 보너스 포인트는 "+bonusPoint+"입니다.";
}
}
package first_project;
public class VIPCustomer extends Customer {
private int agentId;
double saleRatio;
public VIPCustomer(int customerId, String customerName, int agentId) {
super(customerId, customerName);
customerGrade = "VIP";
bonusRatio = 0.05;
saleRatio = 0.1;
this.agentId = agentId;
}
@Override
public int calcPrice(int price) {
bonusPoint += price* bonusRatio;
return price - (int)(price* saleRatio);
}
@Override
public String showCustomerInfo() {
return super.showCustomerInfo() + "담당 상담원 번호는 "+ agentId + "입니다.";
}
public int getAgentId() {
return agentId;
}
}
package first_project;
public class CustomerTest {
public static void main(String[] args) {
Customer customerLee = new Customer(1010, "이순신");
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
Customer customerKim = new VIPCustomer(2020, "김유신", 111);
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
System.out.println("====할인율과 보너스 포인트 계산====");
int price = 10000;
int leePrice = customerLee.calcPrice(price);
int kimPrice = customerKim.calcPrice(price);
System.out.println(customerLee.getCustomerName()+"님의 지불 금액은 "+ leePrice+"원입니다. ");
System.out.println(customerLee.showCustomerInfo());
System.out.println(customerKim.getCustomerName()+"님의 지불 금액은 "+ kimPrice+"원입니다. ");
System.out.println(customerKim.showCustomerInfo());
}
}
결과
이순신님의 등급은 Silver이며, 보너스 포인트는 1000입니다.
김유신님의 등급은 VIP이며, 보너스 포인트는 10000입니다.담당 상담원 번호는 111입니다.
====할인율과 보너스 포인트 계산====
이순신님의 지불 금액은 10000원입니다.
이순신님의 등급은 Silver이며, 보너스 포인트는 1100입니다.
김유신님의 지불 금액은 9000원입니다.
김유신님의 등급은 VIP이며, 보너스 포인트는 10500입니다.담당 상담원 번호는 111입니다.
여기서 주목할 점은 customerLee와 customerKim 모두 Customer형으로 선언되었지만
할인율과 보너스포인트는 각 인스턴스의 메서드에 맞게 계산되었다는 점이다.
즉 같은 상위 클래스 자료형으로 선언하여 생성할 수 있지만 재정의된 메서드는 각각 호출된다.
댓글