
OOP 의 주요 특징 중 하나이다.

같은 부모를 상속받은 클래스는 StandardModel model = new Tanker(); 와 같이 같은 부모클래스 타입으로 들어갈 수 있다.
마찬가지로 Interface 를 구현 받은 클래스 가 해당 인터페이스 타입 의 형태로 들어갈 수도 있다.

다형성을 통해 model 에 new Tanker() 객체를 생성하였으면
이 객체의 useItem() , skill() , jump() 메서드를 model 변수명.메소드로 사용할 수 있다.
다형성을 사용하면 코드의 중복을 줄이고 자원을 효율적으로 사용이 가능하다.

StandardModel 부모 추상클래스 타입 변수에 자식클래스 객체를 담아 저장하면 그 변수는 자식클래스의 멤버 들을 사용할 수 있다.

Ice , Light , Fire 클래스의 부모클래스 Spell 을 만들어 상속시키면
Spell spell = new Fire(); 와 같이 자식 클래스 객체를 담을 수 있다.
이 다음 spell.casting(); 을 switch 문 밖에 시전하면 왼쪽의 각각 메소드를 실행시켜야 하는 중복을 줄일 수 있다.
즉, 다형성에 의해 부모클래스 타입의 변수 에 자식 객체 를 넣을 수 있어
각각의 자식객체의 메서드 호출 을 동일한 변수명 으로 담는 것이 가능하게 되어 중복을 제거할 수 있게 된다.

왼쪽은 오버로딩 을 통해서 같은 이름의 메서드를 자식클래스 타입만 다르게 하여 만든 것이다.
하지만 차량 클래스가 추가될 때마다 오버로딩한 메서드를 계속 만들어 줘야 하는 번거로움이 생긴다.
그래서 각각의 차량 클래스를 상속받는 부모클래스 Car 를 만들어
Car car 타입으로 매개변수를 통일시켜주면 번거로움을 줄일 수 있다.
필드 다형성과 마찬가지로 부모 타입의 매개변수 에도 자식 객체 가 들어갈 수 있기 때문에 가능한 것이다.

1. 이렇게 만들어진 Racer 클래스 의 객체를 생성하여
2. drive 메소드의 매개변수 에 각각 Benz 객체 , Bmw 객체 , Audi 객체 를 넣으면
3. 다형성에 의해 매개변수 Car car 타입에 자식 객체 가 들어가
4. 자식 객체 의 run() 메서드 가 호출되는 결과값을 반환한다.
빙수를 만들어보자.
이 때 Vingsu 부모클래스 가 있고
상속받는 ChocoVingsu , CookieVingsu , RedBeanVingsu 가 있다.

왼쪽과 같이 진행할 경우 각각의 자식클래스 객체를 생성하고 또 메서드들을 일일이 호출하는 번거로움이 발생한다.
오른쪽과 같이 줄이기 위해 다형성을 응용해보자.

VingsuMachine 클래스 를 만들어 makeVingsu 메서드 로 중복되는 메서드들을 넣는다.
이 때 매개변수 다형성에 의해 부모클래스 타입의 매개변수에 자식객체를 넣을 수 있기 때문에 makeVingsu 메서드 만 이용하면 앞선 코드를 줄일 수 있게 된다.
매개변수에 new ChocoVingsu() 와 같이 바로 객체를 생성하였기 때문에 필드 다형성과 같이
VingsuMachine vm = new ChocoVingsu();와 같이 사용하지 않아도 된다.
-자식 클래스 -> 부모 클래스 형태로 들어가는 것을 Promotion(묵시적 형변환) 이라고 부른다.
-부모 클래스 -> 자식 클래스 로 되돌아 가는 것을 Casting(명시적 형변환) 이라고 한다.
앞서 다루었던 다형성은 Promotion (묵시적 형변환) 이었다.
자식 클래스 -> 부모 클래스 로 돌아가면 중복을 줄일 수 있다는 장점이 있지만,
반대로 자식 클래스 고유의 메서드 는 사용이 불가한 단점이 있다.
사용하고 싶으면 본인의 형태로 다시 되돌아와야 한다.

부모 클래스 -> 자식 클래스 로 되돌아 가는 것.
되돌아 올 때는 자신이 어떤 형태였는지를 잘 기억하고 있어야 한다.
여기서는 Mammal mal = new Cat(); 이기 때문에 되돌아 갈 때는
Cat cat = (cat) mal; 으로 자기 자신의 형태로 돌아갈 수 있다.
그렇게 되돌아 가면 자기 자신의 고유의 메서드인 mew() 를 사용할 수 있다.
마찬가지로 Dog 의 경우도 되돌아 갈 수 있지만,
Dog 객체 가 담긴 상태인데 Cat 타입 으로 되돌아가려고 하면
ClassCastException 예외가 발생하므로 꼭 자신이 어떤 형태였는지를 잘 기억하고 있어야 한다.