출간일 2016년 11월 28일
판매가 2000원
형태 ebook
이 책의 모든 내용은 http://ehpub.co.kr에 공개하고 있습니다.
학습에 도움이 되시면 ebook을 구입하여 소장하시면 감사하겠습니다.
언제나 휴일 출판사의 수익금의 대부분은 아프리카에 기부하고 있습니다.
5. 5 안전한 하향 캐스팅을 위한 예약어 instanceof
프로그래밍 언어에서 캐스팅은 형식을 변환하는 것을 말합니다. Java 언어에서 상속 문법을 효과적으로 사용할 수 있게 기반 형식의 변수로 파생 형식 개체를 참조할 수 있게 해 주는데 이를 상향 캐스팅이라 말합니다. 따라서 java 언어에서 상향 캐스팅은 묵시적으로 지원하는 것입니다.
예를 들어 기반 클래스 Musician이 있고 Musician에서 파생한 Pianist 클래스가 있을 때 기반 클래스 Musician 형식 변수 musician에 Pianist 개체를 생성하여 대입하는 것은 매우 자연스러운 코드입니다.
Musician musician = new Pianist();
하지만 반대로 Musician 형식 변수에 참조하는 개체를 파생 클래스 Pianist 형식 변수에 대입하는 것은 묵시적으로 허용하지 않습니다. 이를 허용하지 않는 이유는 자명합니다. 예를 들어 Musician 기반 형식에서 파생한 형식이 Pianist와 Drummer가 있다고 가정합시다. 그리고 Musician 형식 변수 musician에 Drummer 개체를 참조합니다. 이 때 misician 변수를 Pianist 형식 변수에 대입한다면 논리적으로 모순이 발생합니다. 이러한 이유로 하향 캐스팅은 묵시적으로 허용하지 않습니다.
//기반 클래스 public abstract class Musician { public abstract void Play(); } |
//파생 클래스 Drummer public class Drummer extends Musician { @Override public void Play() { System.out.println("두두둥"); } } |
//파생 클래스 Pianist public class Pianist extends Musician { @Override public void Play() { System.out.println("딩동댕"); } public void Tunning(){ System.out.println("도도 레레 미미 파파 솔솔"); } } |
//묵시적 하향 캐스팅 오류 예 public class Program { public static void main(String[] args) { Musician musician = new Drummer(); musician.Play();
Pianist pianist = musician; pianist.Tunning(); } } |
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from Musician to Pianist
at Program.main(Program.java:8) |
[소스 5.11] 묵시적 하향 캐스팅 오류 예
그런데 위의 예처럼 파생 클래스 Pianist에서만 동작하는 메서드가 있을 때 기반 형식으로 참조하는 Painist 개체의 해당 메서드(예제 코드의 Tunning)를 호출할 수 없다면 구현의 한계가 발생할 것입니다.
Java 언어에서는 안전하게 참조하는 개체가 특정 형식인지 확인하는 instanceof 예약어를 제공하고 있습니다. 그리고 원하는 형식인지 확인 후에 명시적으로 캐스팅 연산을 사용하여 하향 캐스팅한다면 안전하게 하향 캐스팅할 수 있습니다.
instanceof 예약어는 개체 instanceof 확인할 클래스명을 통해 논리값을 반환합니다. 그리고 명시적 캐스팅은 (변환할 형식명) 개체 형태로 나타냅니다. 다음은 musician 변수에 참조한 개체가 Pianist 형식 개체인지 확인한 후에 명시적으로 하향 캐스팅하는 예입니다.
if(musician instanceof Pianist)
{
Pianist pianist = (Pianist)musician;
pianist.Tunning();
}
//기반 클래스 public abstract class Musician { public abstract void Play(); } |
//파생 클래스 Drummer public class Drummer extends Musician { @Override public void Play() { System.out.println("두두둥"); } } |
//파생 클래스 Pianist public class Pianist extends Musician { @Override public void Play() { System.out.println("딩동댕"); } public void Tunning(){ System.out.println("도도 레레 미미 파파 솔솔"); } } |
//안전한 하향 캐스팅 예 public class Program { static void Foo(Musician musician) { if(musician instanceof Pianist) { Pianist pianist = (Pianist)musician; pianist.Tunning(); } musician.Play(); } public static void main(String[] args) { Musician musician = new Drummer(); Foo(musician); musician = new Pianist(); Foo(musician); } } |
두두둥 도도 레레 미미 파파 솔솔 딩동댕 |
[소스 5.12] 안전한 하향 캐스팅 예
'언어 자료구조 알고리즘 > 디딤돌 Java 언어 Part1' 카테고리의 다른 글
[Java] 6.2.1 String 클래스의 생성자 (0) | 2016.11.16 |
---|---|
[Java] 6. 2 String 클래스 (0) | 2016.11.16 |
[Java] 6.1 열거형 (0) | 2016.11.15 |
[Java] 6. 배열 및 기본 문법들 (0) | 2016.11.15 |
[Java] 5. 6 모든 클래스의 super 클래스인 Object (0) | 2016.11.14 |
[Java] 5.4 인터페이스 (0) | 2016.11.14 |
[Java] 5.3 추상화 (0) | 2016.11.14 |
[Java] 5.2 다형성 (0) | 2016.04.04 |
[Java] 5. OOP 상속과 다형성, 5.1 상속 (0) | 2016.04.04 |
[Java] 4. 5 정적 멤버와 static 키워드와 상수화에 사용하는 final 키워드 (0) | 2016.04.04 |