instanceof 연산자

Jan 28, 2024
instanceof 연산자
💡
오버라이딩 쓰는게 더 낫다. 근데 못 쓰는 경우가 있을 수도 있으니까...
 
동적바인딩 사용이 불가능 한 경우
💡
Protoss 클래스가 attack 메소드를 안들고 있으니 동적바인딩 사용 불가
package ex06.example6; class Protoss { } class Zealot extends Protoss { public void attack() { System.out.println("질럿이 공격합니다."); } } class Dragoon extends Protoss { public void attack() { System.out.println("드라군이 공격합니다."); } } public class CastingEx01 { public static void main(String[] args) { } }
 
동적바인딩 코드 - 객체를 메소드의 매개변수로 받고 호출하는 ver
package ex06.example6; class Protoss { public void attack() { } } class Zealot extends Protoss { public void attack() { System.out.println("질럿이 공격합니다."); } } class Dragoon extends Protoss { public void attack() { System.out.println("드라군이 공격합니다."); } } public class CastingEx01 { public static void start(Protoss p) { p.attack(); } public static void main(String[] args) { start(new Zealot()); // Zealot z1 = new Zealot(); // z1.attack(); } }
notion image
 

 
notion image
notion image
start(new Zealot()); 와 Zealot z1 = new Zealot(); z1.attack(); 는 같은 코드다.
 

 
객체의 다운 캐스팅 (부모 > 자식 불가!!) - 컴파일 에러
notion image
notion image
부모(Protoss 타입 p)를 자식(Zealot 레퍼런스 타입 z)에게 대입할 수 없다. (반대는 됨) 컴파일 시점에 코드도 만들지 못하는 오류! 컴파일 에러! 다운 캐스팅 불가!
💡
컴파일 에러 : 소스 코드를 컴파일할 때 발생하는 오류로, 컴파일러가 소스 코드를 분석하고 기계어로 변환하는 과정에서 문제가 발생. 컴파일 에러가 해결되지 않으면 프로그램은 실행되지 않는다.
자식형 객체로 부모형을 참조할 수 없다.
 
객체의 강제 형변환 - 런타임 에러?? (물어보기!)
notion image
d1(Protoss 타입)을 더 작은 자식 Dragoon 타입으로 강제형변환 하면 > 실행할 때 오류가 뜸! 런타임 에러!!
💡
런타임 에러 : 코드 칠 때는 오류가 없지만, 실행 시에 오류가 발생한다
notion image
 
<런타임 에러가 발생한 모습>
notion image
notion image
Zealot과 Dragoon은 모두 Protoss의 하위 클래스이지만, Dragoon은 Zealot이 아니므로 형변환이 불가능
notion image
이렇게 수정하면 오류 안남
그럼 이거는 올려보낸 객체 타입이 달라서 그런건가?
 

 
<오류 안남>
package ex06.example6; class Protoss { } class Zealot extends Protoss { public void attack() { System.out.println("질럿이 공격합니다."); } } class Dragoon extends Protoss { public void attack() { System.out.println("드라군이 공격합니다."); } } public class CastingEx01 { public static void start(Protoss p) { Zealot u = (Zealot) p; u.attack(); } public static void main(String[] args) { start(new Zealot()); } }
질럿으로 바꿧더니 오류 안남.
 

 
instanceof = 타입검사 (동적바인딩 못 쓸 때만 사용. 오버라이딩 써라)
'객체 instanceof 클래스' 형태로 사용. 객체가 어떤 클래스로부터 생성되었는지를 확인하는 데에 유용하다. 타입을 검사한 후, 다운캐스팅해서 실행하는 것. (동적바인딩 쓰지 않는다.) * 다운캐스팅은 명시적으로 함.
 
<예시>
package ex06.example6; class Protoss { } class Zealot extends Protoss { public void attack() { System.out.println("질럿이 공격합니다."); } } class Dragoon extends Protoss { public void attack() { System.out.println("드라군이 공격합니다."); } } public class CastingEx01 { public static void start(Protoss p) { if (p instanceof Zealot) { Zealot u = (Zealot) p; u.attack(); } if (p instanceof Dragoon) { Dragoon u = (Dragoon) p; u.attack(); } } public static void main(String[] args) { start(new Zealot()); start(new Dragoon()); } }
p가 크니까 자기를 깎아서 zealot에 넣는거임 >> 그냥 오버라이딩 써라
notion image
 

 
💡
* instanceof는 코드를 수정하는 것 >> 기존 코드를 손 댐 * 오버라이딩은 메서드를 추가하는 것 >> 기존 코드를 손 안댐 > 코드를 수정하는 건 망가질 수 있으니 오버라이딩을 써라. (기존 코드를 손대는 건 위험한 일!! 연결되게 코드를 짜면 나중에 고치다가 큰 일이 날수도) * if-else는 짜지 마라!! 차라리 if를 여러 개 써라 > if-else는 코드가 줄줄줄 이어져 있어서 망가질 위험이 있다.
 

 
💡
통신 = 메서드 호출
 
Share article

codingb