본문 바로가기
BackEnd/Java

[Java] 다형성 Polymorphism

by summer_light 2021. 7. 13.

다형성 Polymorphism

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

코드 측면에서 보면 다형성은 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.
다형성을 위해 자바는 부모 클래스로 타입 변환을 허용해준다.
즉 부모타입에 모든 자식객체가 대입될 수 있다. 이를 이용하여 객체를 부품화할 수 있다. 

단, 다형성은 동적 바인딩(런타임 때 최종 타입이 결정되는 것)이 지원되어야 한다. 

 

EX01. 어벤져스

Hero 클래스를 상속받은 Ironman, Hulk, Spiderman, Thor클래스가 각각의 위치(하늘, 땅, 바다, 우주)를 담은 변수를 갖고, 각기 다른 공격방식(Javis, 주먹, 거미줄, 번개)을 갖도록 하였다.

package polymorphism;

class Hero{
	public String name;
	public void attack() {
		System.out.println("공격");
	}
}

class Ironman extends Hero{
	public String spot = "하늘";
	int suitCount;
	
	public void makeSuit() {
		System.out.println("Javis, 슈트 만들어줘.");
	}
	
	@Override
	public void attack() {
		System.out.println("javis, 공격");
	}
}
class Hulk extends Hero{
	public String spot = "땅";
	@Override
	public void attack() {
		System.out.println("주먹");
	}
}
class Spiderman extends Hero{
	public String spot = "바다";
	@Override
	public void attack() {
		System.out.println("거미줄");
	}
}
class Thor extends Hero{
	public String spot = "우주";
	@Override
	public void attack() {
		System.out.println("번개");
	}
}

public class Polymorphism {
	public static void main(String[] args) {

		Hero h1;//컴파일타임
		h1 = new Ironman();//런타임
		
		Hero[] avengers = new Hero[4];
		
		avengers[0] = new Ironman();
		avengers[1] = new Hulk();
		avengers[2] = new Spiderman();
		avengers[3] = new Thor();
				
		for (Hero hero : avengers) {
			hero.attack();
		}
		
		for (int i = 0; i < avengers.length; i++) {
			avengers[i].attack();
		}
		
	}
}

출력결과

javis, 공격
Javis, 슈트 만들어줘.
Javis, 슈트 만들어줘.
javis, 공격
주먹
거미줄
번개
javis, 공격
주먹
거미줄
번개

 

 컴파일타임, 런타임

		Hero h1;//컴파일타임
		h1 = new Ironman();//런타임

 

※ 자식 객체는 부모 클래스로의 타입 변환을 허용한다.

즉, 부모 객체에 자식 객체를 대입하여 부모 클래스로 타입 변환하는 것은 가능하다.
그러나 자식 객체에 부모 객체를 대입하는 것은 불가능하다. 

		//부모 객체에 자식 객체를 대입하는 것은 가능하지만(결과: 부모)
		//자식 객체에 부모 객체를 대입하는 것은 불가능
		//Hero h = new Ironman(); 가능 
		//Ironman i = new Hero(); 불가

 

※ 자식 클래스에서 정의한 멤버나 메소드 사용하기

  • 방법1) 형변환
    //방법1 형변환
    ((Ironman)h1).makeSuit(); //Javis, 슈트 만들어줘.
    ((Ironman)h1).suitCount = 10; //Javis, 슈트 만들어줘.​
  • 방법2) 새 객체 생성
    //방법2 새 객체 생성 
    Ironman i2 = (Ironman)h1;
    i2.makeSuit();​

 

EX02. 어벤져스2

위치에 따라 다른 Hero를 부를 수 있도록 Hero 클래스에 callHero 메소드를 만든다. 

package polymorphism;

public class Polymorphism02 {
	public static Hero callHero(String spot) {
		
		if(spot.equals("하늘")) {
			return new Ironman();
		}else if(spot.equals("땅")) {
			return new Hulk();
		}else if(spot.equals("바다")) {
			return new Spiderman();
		}else {
			return new Thor();
		}
		
	}
	
	public static void main(String[] args) {
		
		Hero h1 = callHero("바다"); //바다에 해당하는 영웅은 스파이더맨 
		Hero h2 = callHero("땅"); //땅에 해당하는 영웅은 헐크
		
		h1.attack(); //거미줄 //스파이더맨의 공격은 "거미줄" 이므로
		h2.attack(); //주먹 //헐크의 공격은 "주먹" 이므로
		
	}
}

출력결과

거미줄
주먹

 

※ 참고

Hero 클래스의 callHero 메소드를 선언할 때, Hero 클래스에 직접 가서 callHero 메소드를 정의하지 않고

다음과 같이 Polymorphism02 클래스 안에서 외부 클래스인 Hero 클래스의 callHero 메소드를 선언했다. 

package polymorphism;

public class Polymorphism02 {
	public static 외부클래스 메소드이름(파라미터) {
		
		...
		
	}
}

어벤져스2 에서는 아래와 같이 사용 되었다. 

package polymorphism;

public class Polymorphism02 {
	public static Hero callHero(String spot) {
		
		...
		
	}
	
	public static void main(String[] args) {
		
		...
		
	}
}

 

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

[Java] 메모리 Memory  (0) 2021.07.13
[Java] 열거 타입 Enum  (0) 2021.07.13
[Java] 추상 Abstract  (0) 2021.07.13
[Java] 상속과 인터페이스  (0) 2021.07.13
[Java] 자바 API 읽기  (0) 2021.07.09

댓글