본문 바로가기
java

[Java] 레퍼런스타입 - 다형성/캐스트연산자/instanceof

by jinbro 2017. 1. 16.





지난 포스팅에서는 레퍼런스타입 특징에 대해서 알아보았다.

이번 포스팅에서는 레퍼런스타입 중 클래스와 인터페이스가 가지는 다형성에 대해서 알아볼 것이다.


우선 다형성이 대다수 사람들이 하는 정의들을 알아보았다

다형성 : 여러가지 형태를 가질 수 있는 능력 으로 다들 정의를 해놓았더라


찾아본 정의를 토대로 코드들을 살펴본 결과 내가 내린 정의는 이러하다(좀 길다.....)

다형성 : 상속받은 클래스(자식) 혹은 인터페이스 구현된 클래스가 있고, 상속을 해준(부모) 클래스 혹은 인터페이스가 있다. 부모 클래스 혹은 인터페이스를 객체 변수타입으로 두고 자식클래스, 인터페이스 구현된 클래스의 객체를 담을 수 있다.


다형성을 사용한다면 부모 클래스, 인터페이스를 인자로 두고 실제로는 자식, 인터페이스를 구현한 클래스를 인자로 던질 수 있다는 것이다.

아래의 예로 다형성을 테스트해보았다.




 



두 클래스(부모, 자식)가 있다.



1) 부모클래스인 Animal로 객체변수타입을 정해두고 상속클래스인 Dog의 객체를 값에 대입하였다.

2) 다형성으로 인해 대입이 가능하다.

3) 그러나 문제점이 있다. 분명 Dog 객체를 변수에 대입했는데 Dog의 메소드인 bark는 호출되지않는다. 그 이유는 대입한 객체는 Dog이지만 변수의 데이터형은 Animal이기 때문에 변수가 Dog의 메소드가 있는지 없는지 알 수 없기 때문에 호출되지 않고 에러가 나는 것이다.

4) 이를 해결하기 위해서 캐스트 연산자 라는 것이 필요하다.

결론) 다형성이라는 특성으로 부모클래스의 인자 혹은 객체 변수타입으로 자식클래스의 객체를 받을 수 있지만 변수가 부모클래스 타입이기때문에 자식클래스의 메소드를 사용할 수 없다. 사용할 수 있도록 하는 것이 캐스트 연산자이다.




캐스트 연산자는 프리미티브타입에서도 사용이된다.

그러나 프리미티브타입에서의 캐스트 연산자 사용과 레퍼런스타입에서의 캐스트 연산자 사용은 다르다고 한다.

레퍼런스타입에서의 캐스트 연산자 사용은 값 자체의 타입을 바꾸는 것이 아니라 캐스트 하려고 하는 타입에 대해서 사용이 하다라는 것을 보증하는 것이라고 한다.

아래의 실제 코드를 보고 살펴보자.



1) Animal(부모클래스)로 인자 타입을 설정해두고 실제 인자는 Dog(자식클래스)의 객체를 받는다.

2) Dog d1 = (Dog)a; 코드 : Dog 클래스 타입의 변수 d1에는 현재 Animal  클래스 타입의 변수 값이 참조되어있다. Dog 타입의 객체를 받았지만 앞서 설명한대로 Animal 타입의 클래스 변수로 받았기 때문에 a는 Animal형이다. a는 여전히 bark라는 Dog 타입의 메소드를 사용할 수 없기 때문에 캐스트 연산자 (Dog)를 통해서 캐스트 될 수 있음을 보증하고 이를 Dog 타입 변수인 d1에 넣는다. d1을 통해서 bark() 라는 Dog 타입의 메소드를 사용할 수 있게 된다.

결론) 다형성은 되도록이면 부모, 상속 클래스의 공통된 메소드, 값을 뽑아서 사용할 때 쓰면 좋지않을까?

추가) 캐스트 연산자 앞에 있는 코드 instanceof는 런타임 중 a라는 Animal 타입의 클래스 변수가 Dog 타입 클래스로 캐스트가 가능한지를 묻는 코드이다. return 타입은 boolean 으로 flag boolean 변수를 하나 두고 true일 경우 캐스트를 할 수 있도록 코드를 짜면 되겠다.




'java' 카테고리의 다른 글

[Java] java.lang 패키지 : StringBuilder, StringBuffer  (0) 2017.01.20
[Java] java.lang 패키지 : String  (0) 2017.01.20
[Java] 접근제어자  (0) 2017.01.20
[Java] 패키지  (0) 2017.01.20
[Java] 레퍼런스타입  (0) 2017.01.16

댓글