✅🌲강의 복습 노트/패캠 JavaSpring 강의,코드 복습

Part2. 3-6 다형성과 다형성을 사용하는 이유

들판속초록풀 2025. 5. 26. 17:42

다형성(polymorphism)이란

하나의 코드형변환(업캐스팅)을 통해서 여러 자료형으로 구현되어 실행되는 것

같은 코드에서 여러 다른 실행 결과가 나옴

정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나임

다형성을 잘 활용하면 유연하고 확장성있고, 유지보수가 편리한 프로그램을 만들수 있음

 

 

원래는 Java 파일 하나에 클래스 하나를 많이 만드는데  클래스가 여러 개 들어갈 수 도 있다
Java 파일 하나public 클래스한 개이다


 

moveAnimal() 메서드의 매개변수의 자료형은 Animal 이고,  들어가는 객체들의 자료형은 하위 클래스인 human, tiger, eagle 이어서 자동으로 형변환이 된다

코드는 한 줄인데 어떤 데이터 형이 들어갔느냐에 따라, 어떤 인스턴스 형이 들어갔느냐에 따라
movAnimal 메서드의 implementation (실행) 이 달라진다  -->   이게 바로 다형성

상속을 하게 되면 하위 클래스들을 상위 클래스 하나의 타입으로 모두 핸들링할 수 가 있다
이런 것을 클래스 간의 결합도가 굉장히 타이트해진다고 말한다

 


moveAnimal() 메서드의 매개변수인 animal 변수는 자료형이 Animal 클래스이기 때문에  
하위 클래스인 human 클래스의  readBook() 메서드나  tiger 클래스의 hunting() 메서드 호출할 수 없다
호출하고 싶으면 다운 캐스팅을 해야 한다.  (다운 캐스팅은 이후 강의에서)

 

 

class Animal{          // 상위 클래스 Animal 
	
	public void move() {
		System.out.println("동물이 움직입니다.");
	}
	
	public void eating() {
		
	}
}

class Human extends Animal{             // 하위 클래스 1  Human
	public void move() {
		System.out.println("사람이 두발로 걷습니다.");
	}
	
	public void readBooks() {
		System.out.println("사람이 책을 읽습니다.");
	}
}

class Tiger extends Animal{              // 하위 클래스 2  Tiger
	 
	public void move() {
		System.out.println("호랑이가 네 발로 뜁니다.");
	}
	
	public void hunting() {
		System.out.println("호랑이가 사냥을 합니다.");
	}
}

class Eagle extends Animal{                // 하위 클래스 3 Eagle
	public void move() {
		System.out.println("독수리가 하늘을 날아갑니다.");
	}
	
	public void flying() {
		System.out.println("독수리가 날개를 쭉 펴고 멀리 날아갑니다");
	}
}


public class AnimalTest {                  // public 클래스는 Java파일에 1개 있어야 한다

	public static void main(String[] args) {

		Animal hAnimal = new Human();     // 형변환
		Animal tAnimal = new Tiger();     // 자료형은 Animal이지만 생성자는 하위 클래스 생성자
		Animal eAnimal = new Eagle();
		
		AnimalTest test = new AnimalTest();
		test.moveAnimal(hAnimal);
		test.moveAnimal(tAnimal);
		test.moveAnimal(eAnimal);
		                                        // 객체 배열을 위해 만들어진 ArrayList 활용
		ArrayList<Animal> animalList = new ArrayList<Animal>();
		animalList.add(hAnimal);
		animalList.add(tAnimal);
		animalList.add(eAnimal);
		
		for(Animal animal : animalList) {       // 향상된 for문
			animal.move();                 // 다형성 : 같은 코드에서 여러 다른 실행 결과가 나온다
		}
	}	
	
	public void moveAnimal(Animal animal) {
		animal.move();
		
	}
}

 


 

* 다형성을 사용하는 이유

상속과 메서드 재정의를 활용하여 확장성 있는 프로그램을 만들 수 있다

그렇지 않는 경우 메서드마다 많은 if-else if문이 구현되고 코드의 유지보수가 어려워짐

 

상위 클래스에서는 공통적인 부분을 제공하고 하위 클래스에서는 각 클래스에 맞는 기능 구현

여러 클래스하나의 타입(상위 클래스)으로 핸들링 할 수 있음


 

상속을 할 때 상속의 깊이너무 깊게 하는 것은 좋지 않다.

 

ArrayList 는 넣은 순서대로 출력이 된다

 

 

public class GoldCustomer extends Customer{      // Gold 등급 추가

	double saleRatio;
	
	public GoldCustomer(int customerID, String customerName){
		super(customerID, customerName);
	
		customerGrade = "GOLD";
		bonusRatio = 0.02;        // Gold 등급은 2%
		saleRatio = 0.1;
	
	}
	
	public int calcPrice(int price){
		bonusPoint += price * bonusRatio;     //  Gold 등급의 비율은 2%
		return price - (int)(price * saleRatio);   
	}
}

 

 

public class CustomerTest {

	public static void main(String[] args) {
		
		ArrayList<Customer> customerList = new ArrayList<Customer>();
		
		Customer customerLee = new Customer(10010, "이순신");       // 형변환(업캐스팅)
		Customer customerShin = new Customer(10020, "신사임당");
		Customer customerHong = new GoldCustomer(10030, "홍길동");
		Customer customerYul = new GoldCustomer(10040, "이율곡");
		Customer customerKim = new VIPCustomer(10050, "김유신", 12345);
		
		customerList.add(customerLee);         // ArrayList 에 추가
		customerList.add(customerShin);
		customerList.add(customerHong);
		customerList.add(customerYul);
		customerList.add(customerKim);
		
		System.out.println("====== 고객 정보 출력 =======");
		
		for( Customer customer : customerList){        // 향상된 for문
			System.out.println(customer.showCustomerInfo());
		}
		
		System.out.println("====== 할인율과 보너스 포인트 계산 =======");
		
		int price = 10000;
		for( Customer customer : customerList){
			int cost = customer.calcPrice(price);        // calcprice 메서드 사용
			System.out.println(customer.getCustomerName() +" 님이 " +  + cost + "원 지불하셨습니다.");
			System.out.println(customer.getCustomerName() +" 님의 현재 보너스 포인트는 " + customer.bonusPoint + "점입니다.");
		}
	}
}