instanceof 연산자
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 31번째.
이전 레슨에서는 객체가 실제로 캐스팅하려는 타입이 아닌 경우 다운캐스팅이 ClassCastException과 함께 실패할 수 있음을 보여주었습니다. instanceof 연산자는 캐스팅하기 전에 객체의 타입을 확인할 수 있게 함으로써 이 문제를 해결합니다.
구문은 간단합니다: 객체가 해당 클래스(또는 그 하위 클래스 중 하나)의 인스턴스인 경우 object instanceof ClassName은 true를 반환합니다:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // Dog 전용 메서드를 안전하게 호출할 수 있습니다
}이 검사는 캐스팅이 성공할 것임을 보장함으로써 런타임 오류를 방지합니다. 이 연산자는 또한 계층 구조의 부모 타입에 대해서도 true를 반환합니다:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // trueJava 16부터는 패턴 매칭(pattern matching)을 사용하여 검사와 캐스팅을 한 단계로 결합할 수 있습니다:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog'은 이미 캐스팅되어 바로 사용할 수 있습니다
}이 더 깔끔한 구문은 별도의 캐스트 라인을 제거합니다. instanceof는 null에 대해 테스트할 때 false를 반환하므로 별도의 null 체크가 필요하지 않다는 점에 유의하세요.
챌린지
쉬움instanceof 연산자를 사용하여 다양한 차량 유형을 안전하게 식별하고 처리하는 차량 점검 시스템을 구축해 보겠습니다. 차량 계층 구조를 만들고, 각 차량의 특수 기능에 접근하기 전에 실제 유형을 확인하는 코드를 작성하게 됩니다.
코드는 다음 네 개의 파일로 구성됩니다:
Vehicle.java: 모든 차량이 공유하는 기본 클래스를 생성합니다. 모든 차량은model필드(String)를 가집니다. 이를 초기화하는 생성자, 게터 메서드getModel(), 그리고"Inspecting vehicle: " + model을 출력하는inspect()메서드를 포함하세요.Car.java: Vehicle을 상속받는 클래스를 생성합니다. 자동차는 추가로numDoors필드(int)를 가집니다. 부모 클래스 초기화를 위해super를 사용하세요.getModel() + " has " + numDoors + " doors"를 출력하는checkDoors()메서드를 추가하세요.Motorcycle.java: Vehicle을 상속받는 또 다른 클래스를 생성합니다. 오토바이는hasSidecar필드(boolean)를 가집니다. 불리언 값에 따라getModel() + " has a sidecar"또는getModel() + " has no sidecar"를 출력하는checkSidecar()메서드를 추가하세요.Main.java: 여기서instanceof가 필수적으로 사용됩니다! 자동차 모델, 문 개수, 오토바이 모델, 사이드카 유무(true/false)의 네 가지 입력을 받게 됩니다.Car와 Motorcycle을 포함하는
Vehicle참조 배열을 생성하세요. 그런 다음 배열을 루프하며 각 차량에 대해 다음을 수행합니다:- 기본
inspect()메서드를 호출합니다. instanceof를 사용하여 Car인지 확인합니다. 맞다면 안전하게 다운캐스팅하고checkDoors()를 호출합니다.instanceof를 사용하여 Motorcycle인지 확인합니다. 맞다면 안전하게 다운캐스팅하고checkSidecar()를 호출합니다.
- 기본
자동차 모델(String), 문 개수(int), 오토바이 모델(String), 사이드카 유무(boolean)의 네 가지 입력을 받습니다.
출력은 네 줄로 표시되어야 합니다. 각 차량에 대해 점검 메시지가 표시되고 이어서 해당 유형에 특화된 확인 메시지가 표시됩니다. instanceof 연산자를 사용하면 실제 Car 객체에 대해서만 Car 메서드를 호출하고 실제 Motorcycle 객체에 대해서만 Motorcycle 메서드를 호출하도록 보장하여 ClassCastException을 방지할 수 있습니다!
치트 시트
instanceof 연산자는 캐스팅하기 전에 객체가 특정 클래스의 인스턴스인지 확인합니다:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // Dog 전용 메서드를 안전하게 호출할 수 있습니다
}이 연산자는 객체의 클래스와 계층 구조상의 모든 부모 클래스에 대해 true를 반환합니다:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // trueJava 16부터는 패턴 매칭을 통해 확인과 캐스팅을 한 단계로 결합할 수 있습니다:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog'는 이미 캐스팅되어 사용할 준비가 되었습니다
}instanceof 연산자는 null에 대해 테스트할 때 false를 반환하므로, 별도의 null 체크가 필요 없습니다.
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 입력 읽기
String carModel = scanner.nextLine();
int numDoors = Integer.parseInt(scanner.nextLine());
String motorcycleModel = scanner.nextLine();
boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
// TODO: carModel과 numDoors를 사용하여 Car 객체 생성
// TODO: motorcycleModel과 hasSidecar를 사용하여 Motorcycle 객체 생성
// TODO: Car와 Motorcycle을 포함하는 Vehicle 참조 배열 생성
// TODO: 배열을 순회하며 각 차량에 대해 다음을 수행:
// 1. inspect() 메서드 호출
// 2. instanceof를 사용하여 Car인지 확인한 후, 다운캐스팅하여 checkDoors() 호출
// 3. instanceof를 사용하여 Motorcycle인지 확인한 후, 다운캐스팅하여 checkSidecar() 호출
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조