본문 바로가기
Web

[Java] 다형성(Polymorphism) 알아보기

by DuncanKim 2022. 6. 13.
728x90

[Java] 다형성(polymorphism) 알아보기

칼은 참 다양한 종류가 있다.

요리할 때만 해도, 과일칼, 채소자르는 칼, 고기 다지는 칼, 빵칼 등등등..

요리 용도가 아니라 도축, 수술 등등 많은 곳에서 쓰는 것이 칼이다.

 

'칼'이라는 것이 만약에 클래스라면, 또는 인터페이스라고 이해를 해보자.

칼은 '스테인리스'로 되어 있고, '손잡이'가 있으며, '한 면이 날카롭거나 두 면이 날카로워야' 한다.

 

이렇듯 다형성은

:같은 타입이지만 실행 결과가 다양한 '객체'를 이용할 수 있는 성질

을 의미한다.

 

과일칼과 수술용 메스도 어찌보면 같은 타입인데,

과일 칼은 과일 깎을 때 사용하고, 메스는 개복에 사용한다.

실행 결과 자체가 달라지는 것이다.

 


자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하고 있다.

이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있다.


 

 

 

 

다음과 같이 네 개의 클래스가 만들어졌다고 했을 때, 왜 메인 클래스의 네 번째의 식은 오류가 발생할까?

 

세 번째의 경우 참조 변수로 같은 과일칼을 사용했기 때문에 실행이 당연히 가능하다.

 

위의 두 가지 '칼'을 타입으로 자식 클래스의 인스턴스를 각각의 변수가 참조한 다고 했을 때,

이것이 가능 한 이유는


참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문이다.


'칼' 클래스의 멤버 개수는 3개이다.

그렇지만 자식 클래스들의 멤버 개수는 각각 4개이다.

그렇기 때문에 참조가 가능하다.

 

마치 double max = 30; 이 가능한 것처럼 말이다.

double도 공간 자체가 커서(8 bytes) int 정도(4 bytes)는 무난하게 품을 수 있기 때문에 저절로 자동캐스팅된다.

그리고 max라는 변수에 저장이 되는 것이다.

이와 비슷한 것이라고 보면 된다.

 

그렇지만, 네 번째와 같이 4개의 멤버를 가지고 있는 과일칼 타입에

'칼' 클래스의 인스턴스를 담는 것은? 불가능하다.

참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문이다.

 

숫자의 경우에도 이 경우 캐스팅을 해주어야 한다.

int a = (int) 30.0;

 

위와 같이 하나의 클래스를 타입으로 다양한 클래스의 인스턴스를 만들어낼 수 있는 성질

그것이 '다형성'이다.

 

아래에서는 Fruit의 신선도를 가지고 동빈나님의 강의에서 설명을 들은 것이다.

위에서 어느 다형성을 많이 설명했으니, 코드만 두고 마치겠다.

 

 

(1) Fruit 클래스(부모)

public class Fruit {

	String name;
	int price;
	int fresh;
	
	public void show() {
		System.out.println("이름 : " + name);
		System.out.println("가격 : " + price);
		System.out.println("신선도 : " + fresh);
		
	}
}

 

(2) 생성자만 있는 Banana, Peach 클래스(Fruit 상속)

public class Banana extends Fruit{

	public Banana() {
		name = "바나나";
		price = 1300;
		fresh = 90;
	}
	
}
public class Peach extends Fruit{

	public Peach() {
		price = 1500;
		name = "복숭아";
		fresh = 75;
	}
}

 

 

(3) Main 클래스

import java.util.Scanner;
// 다형성의 대표적인 사례

public class FruitMain {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		// 부모 클래스의 변수로 자식 클래스의 인스턴스를 넣어줄 수 있다.
		// 이렇게 해서 아래 처럼 때에 따라 다른 클래스의 인스턴스를 만들어 줄 수 있다.
		System.out.print("바나나 : 1, 복숭아 : 2");
		int input = sc.nextInt();
		Fruit fruit;
		if(input == 1) {
			fruit = new Banana();
			fruit.show();
		}else {
			fruit = new Peach();
			fruit.show();
		}
		sc.close();
	}
}
728x90

댓글