본문 바로가기

자바/자바 개념

[Java] 캐스팅, instanceof 연산자 / 2021.11.01

1. 캐스팅 (casting)

캐스팅이란 타입 변환을 말한다. 자바에서 캐스팅은 업 캐스팅과 다운 캐스팅으로 나뉜다.

 

1-1. 업캐스팅 (upcasting)

서브 클래스의 객체에 대한 레퍼런스를 슈퍼 클래스 타입으로 변환하는 것을 업캐스팅이라고 한다. 

업캐스팅은 슈퍼 클래스의 레퍼런스로 서브 클래스의 객체를 가리키게 한다. (서브 클래스 객체가 슈퍼 클래스 타입으로 형 변환되는 것)

 

예시를 통해서 알아보자.

 

package Chapter5;

class Person{
	String name;
	String id;
	
	public Person(String name){
		this.name = name;
	}
}

class Student extends Person{
	String grade;
	String dapartment;
	
	public Student(String name) {
		super(name);
	}
}

public class UpcastingEx{
	public static void main(String [] args) {
		Person p;
		Student s = new Student("이재문");
		p = s; // 업캐스팅
		
		System.out.println(p.name);
	}
}

 

업캐스팅하는 코드인 p = s;에서 슈퍼 클래스 타입의 레퍼런스 p가 서브 클래스 객체(s)를 가리키도록 치환된다.

업캐스팅을 통해 Person타입의 p는 Student 객체를 가리킨다.

그러나 레퍼런스 p로는 Person클래스의 멤버만 접근할 수 있다. ( p는 Person타입이기 때문에 => 따라서 Student의 grade나 department에는 접근 불가)

위의 코드를 그림으로 설명해 보았다.

 

업캐스팅

* 업캐스팅은 명시적 타입 변환을 하지 않아도 된다. Student객체는 Person 타입이기도 하기 때문이다. 

 

1-2. 다운캐스팅(Downcasting)

업캐스팅과 반대로 캐스팅하는 것을 다운 캐스팅이라고 한다.

업캐스팅된 것을 다시 원상태로 돌리는 것을 말한다. 

위의 예시에서
Person p = new Student("이재문"); // 업캐스팅
Student s = (Student)p; // 다운캐스팅, (Student)의 타입 변환을 반드시 표시

 

* 다운캐스팅은 업캐스팅과 다르게 명시적으로 타입 변환을 지정해야 한다.

 

2. 업캐스팅과 instanceof 연산자

레퍼런스가 가리키는 객체가 어떤 클래스 타입인지 구분하기 위해, 자바에서는 instanceof 연산자를 사용한다.

instanceof 연산자는 이항 연산자로 다음과 같이 사용한다.

 

레퍼런스 instanceof 클래스명

 

instanceof 연산자의 결과 값은 boolean 값으로, 레퍼런스가 가리키는 객체가 해당 클래스 타입의 객체이면 true이고 아니면 false로 계산한다. 

 

예시를 통해서 알아보자.

 

package Chapter5;

class Person { }
class Student extends Person { }
class Researcher extends Person { }
class Professor extends Researcher { }

public class InstanceofEx {
	static void print(Person p) {
		if(p instanceof Person)
			System.out.println("Person ");
		if(p instanceof Student)
			System.out.println("Student ");
		if(p instanceof Researcher)
			System.out.println("Researcher ");
		if(p instanceof Professor)
			System.out.println("Professor ");
		System.out.println();
	}
	public static void main(String [] args) {
		System.out.print("new Student() ->\t"); print(new Student());
		System.out.print("new Researcher() ->\t"); print(new Researcher());
		System.out.print("new Professor() ->\t"); print(new Professor());
	}
}

 

실행결과 : 

 

new Student() -> Person Student 
// new Student() 객체는 Person타입이기도 하고 Student타입이기도함
new Research() -> Person Researcher 
// new Research() 객체는 Person타입이기도 하고 Researcher타입이기도함
new Professor() -> Person Researcher Professor
// new Professor() 객체는 Person타입이기도 하고 Researcher타입이기도하고 Professor타입이기도함