Java & Kotlin
[Java 객체지향] 다형성
Sue
2022. 1. 31. 21:16
다형성 (Polymorphism)
- 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
- 같은 코드에서 다른 실행 결과가 나온다.
- 정보은닉, 상속과 더불어 객체지향 프로그래밍에서 가장 큰 특징 중 하나이다.
- 유연하고, 확장성있고, 유지보수가 쉬운 프로그램을 만들 수 있다.
- 상속, 오버라이딩, 오버라이딩 등을 활용해서 구현할 수 있다.
예제 코드
AnimalTest.java
package ch06;
class Animal{ // 상위 클래스
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal{ // 하위 클래스 1
public void move() {
System.out.println("사람이 두 발로 걷습니다.");
}
public void readBook() {
System.out.println("사람이 책을 읽습니다.");
}
}
class Tiger extends Animal{ // 하위 클래스 2
public void move() {
System.out.println("호랑이가 네 발로 뜁니다.");
}
public void hunting() {
System.out.println("호랑이가 사냥을 합니다.");
}
}
class Eagle extends Animal{ // 하위 클래스 3
public void move() {
System.out.println("독수리가 하늘을 날아다닙니다.");
}
public void flying() {
System.out.println("독수리가 날개를 펴고 멀리 날아갑니다.");
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal hAnimal = new Human(); // 상위 클래스로 각 하위 인스턴스 생성
Animal tAnimal = new Tiger();
Animal eAnimal = new Eagle();
hAnimal.move(); // 같은 이름의 메서드 호출 (재정의됨)
tAnimal.move();
eAnimal.move();
}
}
수행 결과
사람이 두 발로 걷습니다.
호랑이가 네 발로 뜁니다.
독수리가 하늘을 날아다닙니다.
다형성을 사용하는 이유
- 다른 동물을 추가하는 경우 쉽게 클래스를 만들고 메서드만 오버라이딩 해주면 됨
- 상속과 오버라이딩으로 확장성 있는 프로그램을 구현할 수 있다.
- 다형성을 사용하지 않는다면 하나의 클래스에 모든 코드를 다 넣어야 한다.
- 유지보수가 어려워진다.
- 모든 메서드마다 if-else if 문으로 각 속성에 맞는 기능을 넣어주어야 한다. (추가될때도 마찬가지)
- 만약 if-else if 문이 있는 메서드가 너무 많다면 클래스 분리를 고려해볼것.
- 상위 클래스에서는 공통적인 부분을 구현하고 하위 클래스에서는 각 클래스의 기능에 맞는 메서드를 구현하는 것이 좋다.
- 이럴 경우 여러 클래스를 하나의 타입(상위 클래스)으로 핸들링할 수 있다는 장점이 있다.
멤버십 프로그램 확장 - GOLD 등급 회원 만들기
새로운 요구사항이 들어왔다. 일반 고객과 VIP 고객의 중간 멤버십인 GOLD 등급을 만들고 다음과 같은 혜택을 제공한다.
1) 제품을 구입할 때 10% 할인해준다.
2) 보너스 포인트는 2%를 적립해준다.
GoldCustomer.java
package ch06;
public class GoldCustomer extends Customer { // Customer 상속
double salesRatio; // 할인율 변수 선언
public GoldCustomer(String customerName, int customerId) { // 생성자로 상위 클래스의 매개변수와 초기화값 지정
super(customerName, customerId);
customerGrade = "GOLD";
bonusRatio = 0.02;
salesRatio = 0.1;
}
public int calcPrice(int price) { // Gold Customer의 calcPrice
bonusPoint += price * bonusRatio;
return (int)(price * (1-salesRatio));
}
}
VIPCustomer.class
상담원 정보를 출력하는 부분 추가
public String showCustomerInfo() { // showCustomerInfo() 재정의
return super.showCustomerInfo() + "담당 상담원 번호는 " + agentId + "입니다.";
}
CustomerTest.class
Customer 타입(상위 클래스 타입)의 ArrayList를 만들고 하위 클래스의 각 인스턴스를 만들어서 삽입
cost 변수에는 ArrayList에 저장된 각 인스턴스마다 calcPrice() 메서드로 가격을 계산해주는데, 이때 인스턴스마다 다른 가격이 저장된다. (다형성)
package ch06;
import java.util.ArrayList;
public class CustomerTest {
public static void main(String[] args) {
int price = 10000;
ArrayList<Customer> customerList = new ArrayList<>(); // Customer 타입의 ArrayList 생성
Customer customerLee = new Customer("Lee",1000); // 각 타입의 객체 만들기
Customer customerKim = new VIPCustomer("Kim",10000,"A");
Customer customerPark = new GoldCustomer("Park",5000);
customerList.add(customerLee); // ArrayList에 각 객체 넣음
customerList.add(customerKim);
customerList.add(customerPark);
for(Customer customer : customerList) {
int cost = customer.calcPrice(price); // 각 고객이 지불할 가격 저장
System.out.println(customer.getCustomerName() + "님이 " + cost + "원을 지불하였습니다.");
System.out.println(customer.showCustomerInfo());
}
}
}