본문 바로가기
language/JAVA

[JAVA] 다형성 / instanceof

by susu2 2021. 8. 4.

상속과 함께 🌸 자바의 꽃🌼  다형성입니다.

어떻게 보면 간단한 개념인데 또 하다보면 헷갈리는 개념이기 때문에 잘 이해하고 넘어가야겠습니다!! 

 

1. 개념 

-하나의 객체가 여러가지 타입을 가질 수 있는 것

-부모클래스 타입의 참조변수로 자식클래스 타입의 인스턴스를 참조할 수 있다.

 

예제

//부모 클래스 생성
class ParentClass {
	void print() {
		System.out.println("ParentClass의 print메서드");
	}
} 

//자식클래스가 부모클래스를 상속받음
class ChildClass extends ParentClass {
	void print() {
		System.out.println("ChildClass의 print메서드");
	}
	void action() {
		System.out.println("ChildClass의 action메서드");
	}
} 


ParentClass p1 = new ParentClass(); // O
ParentClass p2 = new ChildClass(); // O
ChildClass c1 = new ChildClass(); // O
ChildClass c2 = new ParentClass(); // X

위의 예제를 보면 같은 타입의 객체를 생성하는 것은 당연히 가능하다.

자식 클래스 타입의 참조변수로 부모 클래스 객체를 참조하게 하는 것도 가능하다.

그러나, 그 반대는 불가능하다. 자식 클래스의 멤버개수가 부모 클래스의 멤버개수보다 더 많기 때문이다.

🌟   클래스는 상속을 통해 확장될 수는 있지만 축소될 수는 없기 때문에, 부모 클래스의 멤버 개수는 항상 자식 클래스보다 적거나 같다.

 

 

2. 형변환 

primitive type과 마찬가지로 reference type도 형변환이 가능하다.

단, 서로 상속관계에 있는 클래스 사이에서만 가능하다. (부모-자식 관계의 형변환)

 

예제

class ParentClass {}
class ChildClass extends ParentClass {}

ParentClass p1 = null;
ParentClass p2 = new ParentClass();
ChildClass c1 = new ChildClass;

//자식타입을 부모타입에 (형변환 생략 O)
p1 = c1;

//부모타입을 자식타입에 (형변환 명시)
c1 = (ChildClass) p2;

reference type의 형변환도 마찬가지로 작은 타입에서 큰 타입으로 형변환 할 때에는 생략이 가능하지만, 반대의 경우에는 형변환을 명시해야한다.

 

ParentClass parent = new ParentClass();
ChildClass child = new ChildClass();

//컴파일은 OK, 단 실행 시 에러
child = (ChildClass) parent;

위의 코드를 보면 문제 없이 잘 실행되어야 할 것같다.

하지만 부모타입의 인스턴스를 자식타입의 참조변수로 참조하는 것은 허용되지 않기 때문에 실행 시 에러가 발생한다.

따라서 형변환 시 참조변수가 가리키고 있는 인스턴스의 타입이 무엇인지 확인해야한다.

 

 

3. instanceof 

참조변수가 참조하고 있는 인스턴스의 타입을 확인하기 위해 instanceof 연산자를 사용한다.

참조변수 instanceof 클래스명

상기와 같이 사용하면 된다. 반환은 boolean값(true or false)이다.

해당 참조변수가 클래스 타입으로 형변환이 가능하면 true를 반환한다.

형변환이 불가능하거나 참조변수가 null값 일 경우, false를 반환한다.

 

예제

class ParentClass {}
class ChildClass extends ParentClass {}

ParentClass p1 = new ParentClass();
ChildClass c1 = new ChildClass();

System.out.println(p1 instanceof ChildClass); //false
System.out.println(c1 instanceof ParentClass); //true

 

댓글