본문 바로가기
언어/JAVA

다형성과 다형성을 사용하는 이유

by step 1 2021. 4. 18.
반응형

다형성

  • 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
  • 같은 코드에서 여러 다른 실행 결과가 나옴
  • 정보은닉, 상속과 더불어 객체지향 프로그램의 가장 큰 특징 중 하나임
  • 다형성을 잘 활용하면 유연하고 확장성있고, 유지보수가 편리한 프로그램을 만들 수 있음
  • 오버라이딩을 통해서 사용 가능

 

package ch28;

import java.util.ArrayList;
import java.util.Iterator;

class Animal {
	
	public void move() {
		System.out.println("동물이 움직입니다.");
	}
	
	public void eating() {
		System.out.println("밥을 먹는다");
	}
}

class Human extends Animal {

	@Override
	public void move() {
		
		System.out.println("사람이 두 발로 걷습니다");
	}
	
	public void readBook() {
		System.out.println("사람이 책을 읽습니다.");
	}
	
}

class Tiger extends Animal {

	@Override
	public void move() {
		System.out.println("호랑이가 네 발로 뜁니다.");
	}
	public void hunting() {
		System.out.println("호랑이가 사냥을 합니다.");
	}
	
}

class Eagle extends Animal {

	@Override
	public void move() {
		System.out.println("독수리가 하늘을 날아 다닙니다.");
	}
	public void hunting() {
		System.out.println("독수리가 양날개를 쭉 펴고 날아다닙니다.");
	}
	
}
public class AnimalTest {

	public static void main(String[] args) {
		
		Animal hAnimal = new Human();
		Animal tAnimal = new Tiger();
		Animal eAnimal = new Eagle();
		
		AnimalTest test = new AnimalTest();
//		test.moveAnimal(hAnimal);
//		test.moveAnimal(tAnimal);
//		test.moveAnimal(eAnimal);
		
		ArrayList<Animal> animalList = new ArrayList<>();
		animalList.add(hAnimal);
		animalList.add(tAnimal);
		animalList.add(eAnimal);
		
		for (Animal animal : animalList) {
			animal.move();
		}
	}
	
	public void moveAnimal(Animal animal) {
		animal.move();
		animal.eating();
	}
}

결과

 

 

다형성을 사용하는 이유

  • 다른 동물을 추가하는 경우
  • 상속과 메서드 재정의를 활용하여 확장성 있는 프로그램을 만들 수 있음
  • 그렇지 않는 경우 많은 if-else if문이 구현되고 코드의 유지보수가 어려워짐
  • 상위 클래스에서는 공통적인 부분을 제공하고 하위 클래스에서는 각 클래스에 맞는 기능을 구현
  • 여러 클래스를 하나의 타입(상위 클래스)으로 핸들링 할 수 있음

 

다형성을 활요한 멤버십 프로그램 확장

일반 고객과 VIP고객 중간 멤버십 만들기

고객이 늘어 일반 고객보다는 많이 구매하고 VIP보다는 적게 구매하는 고객에게도 혜택을 주기로 하였다.

GOLD 고객 등급을 만들고 혜택은 다음과 같다

제품을 살때는 10% 할인해준다.

보너스 포인트는 2%를 적립해준다

 

package ch28;

public class Customer {

	// 상속받을 클래스에서 사용하기 위해 protected로 지정
	protected int customerID;
	protected String customerName;
	protected String customerGrade;
	int bonusPoint;
	double bonusRatio;
	
//	public Customer() {
//		
//		customerGrade = "Silver";
//		bonusRatio = 0.01;
//		System.out.println("Customer() call");
//	}
	
	// 디폴트 생성자 없애고 매개변수가 있는 생성자 추가
	public Customer(int CustomerID, String customerName) {
		this.customerID = customerID;
		this.customerName = customerName;
		
		customerGrade = "Silver";
		bonusRatio = 0.01;
		
		//System.out.println("Customer(int, String) call");
	}
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		return price;
	}
	
	public String showCustomerInfo() {
		return customerName + "님의 등급은 " + customerGrade + "이며, 보너스 포인트는 " + bonusPoint + "입니다.";
	}

	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;
	}
	
	
}

 

package ch28;

public class VIPCustomer extends Customer {

	double saleRatio;
	private String agentID;

//	public VIPCustomer() {
//		bonusRatio = 0.05;
//		saleRatio = 0.1;
//		customerGrade = "VIP";
//		System.out.println("VIPCustomer() call");
//	}

	// 보통 상위클래스 생성자 형태와 맞춰서 생성
	public VIPCustomer(int CustomerID, String customerName) {
		super(CustomerID, customerName);
		
		customerGrade = "VIP";
		bonusRatio = 0.05;
		saleRatio = 0.1;
		//System.out.println("VIPCustomer(int, String) call");
	}
	
	

	@Override
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		price -= (int)(price * saleRatio);
		return price;
	}



	public String getAgentID() {
		return agentID;
	}

	public void setAgentID(String agentID) {
		this.agentID = agentID;
	}

}

 

package ch28;

public class GoldCustomer extends Customer{

	double salesRatio;
	
	public GoldCustomer(int CustomerID, String customerName) {
		super(CustomerID, customerName);

		customerGrade = "Gold";
		salesRatio = 0.1;
		bonusRatio = 0.02;
	}
	
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		return price - (int)(price * salesRatio);
	}

	
}

 

package ch28;

import java.util.ArrayList;

public class CustomerTest {

	public static void main(String[] args) {
		
		ArrayList<Customer> customersList = new ArrayList<>();
		
		Customer customerT = new Customer(10010, "Tomas");
		Customer customerJ = new Customer(10020, "James");
		Customer customerE = new GoldCustomer(10030, "Edward");
		Customer customerP = new GoldCustomer(10040, "Percy");
		Customer customerK = new VIPCustomer(10050, "Kim");
		
		customersList.add(customerT);
		customersList.add(customerJ);
		customersList.add(customerE);
		customersList.add(customerP);
		customersList.add(customerK);
		
		for (Customer customer : customersList) {
			System.out.println(customer.showCustomerInfo());
		}
		
		int price = 10000;
		for (Customer customer : customersList) {
			int cost = customer.calcPrice(price);
			System.out.println(customer.getCustomerName() + "님이 " + cost + "원 지불하셨습니다.");
			System.out.println(customer.getCustomerName() + "님의 현재 보너스 포인트는 " + customer.bonusPoint + " 입니다.");
			System.out.println("=========================");
		}
	}
}

 

결과

반응형