본문 바로가기

Language/Java

[Java] 다형성(polymorphism)

다형성이란 하나의 코드가 여러 자료형으로 구현되어 실행되는 것을 말한다. 

즉 같은 코드에서 여러 실행 결과가 나오는 것이다.

 

[실습] 다형성 테스트하기
package polymorphism;

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

class Human extends Animal {
	public void move() {
		System.out.println("사람이 두 발로 걷습니다.");
	}
}

class Tiger extends Animal {
	public void move() {
		System.out.println("호랑이가 네 발로 뜁니다.");
	}
}

class Eagle extends Animal {
	public void move() {
		System.out.println("독수리가 하늘을 납니다.");
	}
}

public class AnimalTest1 {
	public static void main(String[] args) {
		AnimalTest1 aTest = new AnimalTest1();
		aTest.moveAnamal(new Human());
		aTest.moveAnamal(new Tiger());
		aTest.moveAnamal(new Eagle());
	}
	
	public void moveAnamal(Animal animal) { //매개변수의 자료형 상위클래스
		animal.move();  // 재정의된 매서드가 호출됨
	}
}

AnimalTest1 클래스에 만든 moveAnimal() 메서드는 어떤 인스턴스가 매개변수로 넘어와도 모두 Animal형으로 변환한다.

매개변수가 전달되는 부분에 Human 인스턴스가 전달된다면

Animal ani = new Human();

이렇게 형 변환된다.

Animal에서 상속받은 클래스가 매개변수로 넘어오면 모두 Animal형으로 변환되므로 animal.move() 메서드를 호출할 수 있다.

가상 메서드 원리에 따라 animal.move() 메서드가 호출하는 메서드는 매개변수로 넘어온 실제 인스턴스 메서드이다.

animal.move() 코드는 변함이 없지만 어떤 매개변수가 넘어왔느냐에 따라 출력문이 달라지는데 이것이 다형성이다.

여기에 다른 동물이 새로 추가될 때 각 자료형에 따라 코드를 다르게 구현한다면 코드는 훨씬 복잡해지고 내용도 길어진다.

상위 클래스에서 공통부분의 메서드를 제공하고, 하위 클래스에서는 그에 기반한 추가 요소를 덧붙여 구현하면 코드 양도 줄어들고 유지보수도 편리하다.

또 필요에 따라 상속받은 모든 클래스를 하나의 상위 클래스로 처리할 수 있고 다형성에 의해 각 클래스의 여러 가지 구현을 실행할 수 있으므로 프로그램을 쉽게 확장할 수 있다.

 

[실습] 고객 관리 프로그램 완성하기 (1)
package polymorphism;

public class Customer {
	protected int customerID;
	protected String customerName;
	protected String customerGrade;
	int bonusPoint;
	double bonusRatio;

	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 + "입니다.";
	}

	// protected 예약어로 선언한 변수를 외부에서 사용할 수 있도록 get(), set() 메서드 추가
	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;
	}
}

 

[실습] 고객 관리 프로그램 완성하기 (2)
package polymorphism;

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;
	}
	
	public int calcPrice(int price) {  // 지불 가격 메서드 재정의
		bonusPoint += price * bonusRatio;
		return price - (int)(price * saleRatio);
	}
	
	public String showCustomerInfo() {
		return super.showCustomerInfo() + " 담당 상담원 번호는 " + agentID + "입니다.";
	}
	
	public int getAgentID() {
		return agentID;
	}
}

 

[실습] 고객 관리 프로그램 완성하기 (3)
package polymorphism;

public class CustomerTest {
	public static void main(String[] args) {
		Customer customerLee = new Customer();
		customerLee.setCustomerID(10010);
		customerLee.setCustomerName("이순신");
		customerLee.bonusPoint = 1000;
		
		System.out.println(customerLee.showCustomerInfo());
		
		Customer customerKim = new VIPCustomer(10020, "김유신", 12345);
		customerKim.bonusPoint = 1000;
		
		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());
	}
}

 

'Language > Java' 카테고리의 다른 글

[Java] 다운 캐스팅과 instanceof  (0) 2022.12.20
[Java] 다형성 활용하기  (0) 2022.12.19
[Java] 메서드 오버라이딩  (1) 2022.12.13
[Java] 상속에서 클래스 생성과 형 변환  (0) 2022.11.20
[Java] 상속이란?  (0) 2022.11.17