다형성이란 하나의 코드가 여러 자료형으로 구현되어 실행되는 것을 말합니다.
다형성을 활용한 프로그램의 확장성
instancce : 실체 - 실제로 존재한다.
클래스라고 하는 객체의 정의(존재x) → new → 힙공간에 존재(생성된 객체)
instanceof : 객체의 생성된 출처를 확인하는 연산자
c instanceof C : c라고 하는 참조변수가 가리키는 객체가 C클래스로 부터 만든 객체인가?(객체의 포함관계)
이 연산자는 어느 객체 변수가 어느 클래스 타입인지 판별해 true/false를 반환해준다. 사용시 주의할 점은 instanceof 연산자는 객체에 대한 클래스(참조형) 타입에만 사용할 수 있다는 점이다. (int, double 같은 primitive 타입에는 사용 불가능)
public class Ex03 {
public static void main(String[] args) {
C c = new C();
A a = c;
System.out.println(c instanceof C); //true
System.out.println(c instanceof B); //true
System.out.println(c instanceof A); //true
System.out.println(a instanceof C); //true
}
}

위와 같은 계층 구조에서 상위 클래스를 자료형으로 선언하는
Animal ani = new Human();업캐스팅을 사용할수있다. 이때 생성된 인스턴스 Human은 Animal형 입니다. 이렇게 Animal형으로 형 변환이 이루어진 경우에는 Animal 클래스에서 선언한 메서드와 멤버 변수만 사용할 수 있습니다.
다시 말해 Human 클래스에 더 많은 메서드가 구현되어 있고 다양한 멤버 변수가 있다고 하더라도 자료형이 Animal형인 상태에서는 사용할 수가 없습니다. 따라서 필요에 따라 다시 원래 인스턴스의 자료형(여기에서는 Human 형)으로 되돌아가야 하는 경우가 있습니다.
이렇게 상위 클래스로 형 변환 되었던 하위 클래스를 다시 원해 자료형으로 형 변환하는 것을 다운 캐스팅(down casting)이라고 합니다.
그렇지만 다운캐스팅을 하게되면 자바에서는 다운 캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야 변환할 때 오류를 막을 수 있습니다.
아래는 원래 자료형이 다르게 업캐스팅한 두객체를 생성하고, 다운캐스팅을 할때의 오류를 보여줍니다.
D클래스를 참조해준 A클래스 타입(자료형)으로 생성된 ad객체
C클래스를 참조해준 A클래스 타입(자료형)으로 생성된 ac객체
C클래스 자료형인 c참조변수에 ad,ac객체를 대입하면 오류가 발생
public class Ex04 {
public static void main(String[] args) {
A ad = new D();
//업캐스팅(D클래스로 객체를 생성하고, 그 주소를 A자료형인 ad참조변수에 대입)
A ac = new C(); //업캐스팅
//C c = ad; 오류발생
//C c = ac; 오류발생
//C c = (C)ad; 강제형변환도 오류발생
if(ad instanceof C){ //false
C c = (C)ad; //다운캐스팅
}
if(ac instanceof C){ //true
C c = (C)ac; //다운캐스팅
}
}
}
package exam03;
import exam01.A;
public class Ex01 {
public static void main(String[] args) {
Human human = new Human(); //자료형을 Human, Animal가능
//human.move();
Tiger tiger = new Tiger(); //자료형을 Tiger, Animal가능
//tiger.move();
Bird bird = new Bird(); //자료형을 Bird, Animal가능
//bird.move();
Animal[] animals = new Animal[3];
animals[0] = human;
animals[1] = tiger;
animals[2] = bird;
for(int i=0; i< animals.length; i++){
animals[i].move();
}
}
}
public class Ex02 {
public static void main(String[] args) {
Animal[] animals = {new Human(), new Bird(), new Tiger()};
for(Animal animal : animals){
animal.move();
}
}
}
package exam03;
public class Ex02 {
public static void main(String[] args) {
Animal[] animals = {new Human(), new Bird(), new Tiger()};
for(Animal animal : animals){
animal.move();
if(animal instanceof Human){
Human human = (Human)animal;//다운캐스팅
human.reading();
}else if(animal instanceof Tiger){
Tiger tiger = (Tiger) animal;//다운캐스팅
tiger.hunting();
}
//human.reading(); //animal이 human bird tiger을 다가지고있어서 오류
}
}
}