일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이클립스 오라클 연동
- AOP란?
- static메서드
- IP
- 다중 모달창
- SUB Query
- 리스트 모달창
- Java
- 싱클톤패턴
- order by
- oracle 연동
- 스프링 모달창
- 상속
- spring annotation
- 객체협력
- singleton
- 오라클 비교연산자
- static
- 사용자 데이터그램 프로토콜
- static 예제
- Servlet 맵핑
- GROUP BY
- 템플릿
- 추상 메서드
- 다운캐스팅
- 형변환
- 깃 명령어
- downcasting
- react
- 모달창 여러개
- Today
- Total
모든지 기록하자!
[Java] 다운 캐스팅과 instanceof 본문
상위 클래스로 형 변환되었던 하위 클래스를 다시 원래 자료형으로 형 변환하는 것을
다운 캐스팅(down casting) 이라고 한다.
instanceof
상속관계를 보면 모든 인간은 동물이지만 모든 동물이 인간은 아니다.
따라서 다운 캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야
변환할 때 오류를 막을 수 있다. 이것을 확인하는 예약어가 ' instanceof ' 다.
Animal hAnimal = new Human();
if(hAnimal instanceof Human // hAnimal 인스턴스의 자료형이 Human형이라면
Human human = (Human)hAnimal; // 인스턴스 hAnimal을 Human형으로 다운캐스팅
}
참조 변수 hAnimal은 원래 Human형으로 생성되었지만 Animal형으로 형 변환되었다.
instanceof 예약어는 왼쪽에 있는 변수의 원래 인스턴스형이 오른쪽 클래스 자료형인가를 확인한다.
instanceof의 반환 값이 true면 다운 캐스팅을 한다. 이때 Human human = (Human)hAnimal; 과 같이
명시적으로 자료형을 써줘야 한다. 상위 클래스로는 묵시형으로 형 변환이 되지만 하위 클래스로
형 변환을 할 때는 명시적으로 해야한다.
원래 자료형이 Human형이 아닌 경우
Animal ani = new Tiger();
Human h = (Human)ani;
이렇게 코딩해도 컴파일 오류는 나지 않는다. 이유는? Tiger 인스턴스는 Animal형으로 자동 형 변환이 된다.
변수 h의 자료형 Human과 강제 형 변환되는 ani의 (Human) 형이 동일하기 때문에 컴파일 오류는 나지 않는다.
이 코드를 실행하면 실행 오류가 발생한다.
아래 예제로 확인해보자
import java.util.ArrayList;
class Animal{ // 상위 클래스 Animal
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal{ // Animal을 상속받은
public void move() { // Human 클래스
System.out.println("사람이 두발로 걷습니다.");
}
public void readBook() {
System.out.println("사람이 책을 읽습니다.");
}
}
class Tiger extends Animal{ // Animal을 상속받은
public void move() { // Tiger 클래스
System.out.println("호랑이가 네발로 뜁니다.");
}
public void hunting() {
System.out.println("호랑이가 사냥을 합니다.");
}
}
class Eagle extends Animal{ // Animal을 상속받은
public void move() { // Eagle 클래스
System.out.println("독수리가 하늘을 날읍니다.");
}
public void flying() {
System.out.println("하늘을 날아갑니다.");
}
}
public class AnimalTest {
ArrayList<Animal> aniList = new ArrayList<Animal>();
// 배열의 자료형을 Animal로 지정 했다.
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.addAnimal();
System.out.println("===원래 형으로 다운 캐스팅===");
test.testCasting();
}
public void addAnimal() {
aniList.add(new Human()); // ArrayList에 추가되면서
aniList.add(new Tiger()); // Animal형으로 형 변환
aniList.add(new Eagle());
for(Animal ani: aniList) { // 배열 요소를 Animal형으로 꺼내서
ani.move(); // move()를 호출하면 재정의된 함수가 호출된다.
}
}
public void testCasting() {
for(int i=0; i<aniList.size(); i++) { // 모든 배열 요소를 하나씩 돌면서
Animal ani = aniList.get(i); // Animal형으로 가져온다.
if(ani instanceof Human) { // animal이 Human인지 확인
Human human = (Human)ani; // Human이면 Human형으로 다운 캐스팅한다.
human.readBook();
}
else if(ani instanceof Tiger) {
Tiger tiger = (Tiger)ani;
tiger.hunting();
}
else if(ani instanceof Eagle) {
Eagle eagle = (Eagle)ani;
eagle.flying();
}
else {
System.out.println("지원되지 않는 기능입니다.");
}
}
}
}
배열의 요소가 Animal형이므로 각 클래스에서 제공하는 readBook(), hunting(), flying() 메서드를
사용할 수 없다. 자료형이 Animal인 상태이기 때문이다. readBook(), hunting(), flying()을 호출하려면
원래 자료형으로 다운 캐스팅되어야 한다.
출력결과
'Java' 카테고리의 다른 글
[Java] 템플릿(template) 메서드 , final 예약어 (예제 : Player) (0) | 2021.05.18 |
---|---|
[Java] 추상 클래스 ( abstract class ) (예제 : AI Car) (1) | 2021.05.18 |
[Java] 다형성 ( Polymorphism) (예제: 고객관리) (0) | 2021.05.17 |
[Java] 상속 - 오버라이딩(overriding) , 형 변환 (예제 : 고객관리) (0) | 2021.05.16 |
[Java] 상속 - 형 변환, super, 생성자 (예제: 고객관리) (0) | 2021.05.15 |