* 레퍼런스 형변환
- 참조형(레퍼런스타입) 끼리의 형변환 (상속 관계에서만 사용 가능)
- 참조형 변수를 사용하여 다른 타입의 인스턴스(객체)를 참조하기 위해 변환하는 것.
- 업캐스팅(Up casting)과 다운캐스팅(Down casting)으로 분류됨
1. 참조데이터타입에서의 묵시적(자동) 형변환 = 업캐스팅
2. 참조데이터타입에서의 명시적(자동) 형변환 = 다운캐스팅
=> 이전에 이미 업캐스팅 된 인스턴스를 다시 다운캐스팅 하는 경우
* 클래스들의 관계 (Has - a, Is - a)
1. Has-a (포함관계)
- 어떤 객체가 다른 객체에 포함되는 관계
- 대부분의 클래스들의 관계는 Has-a 관계가 적용됨
- 자동차 has a 타이어, 스마트폰 has a 스피커, 영웅 has a 무기
1)집합관계 : 필수아님
- 객체가 다른 객체에 포함될 때 해당 객체가 없어도 동작에 문제가 없는 관계
=> 객체 상호간의 라이프 사이클이 다른 관계
ex. 자동차 has a 라디오
컴퓨터 has a 스피커
영웅 has a 무기
2)구성관계 : 필수!
- 객체가 다른 객체에 포함될 때 해당 객체 없이는 동작이 불가능한 관계
=> 객체 상호간의 라이프 사이클이 동일한 관계
ex. 자동차 has a 엔진, 컴퓨터 has a CPU
2. Is-a 관계(상속 관계)
- 비슷한 속성 및 동작을 갖는 객체 사이의 관계
ex. 초등학생, 중학생, 고등학생 객체들의 공통점은 학생
=> 이때, 학생은 초등학생, 중학생, 고등학생의 상위개념이므로 모두를 포함함
=> 초등학생 is a 학생 => 학생의 모든 구성요소는 초등학생이 갖고 있음
스마트폰 is a 핸드폰 => 핸드폰의 모든 구성요소는 스마트폰이 갖고 있음
* 반대는 안됨.
학생 is a 초등학생 (X)
동물 is a 강아지 (X)
- Is-a 관계가 성립하는 경우 좌변의 객체는 우변의 객체를 상속받아 정의한 객체 성립
- Is-a 관계를 판별하는데 사용하는 연산자 : instanceof 연산자
3. instanceof 연산자
- 좌변의 객체(참조변수)가 우변(클래스) 타입인지 판별하는 연산자
- 판별 결과는 boolean타입으로 리턴되며, 결과값이 true이면 형변환 가능한 관계
(=> 업캐스팅 도는 다운캐스팅 모두 ture가 리턴됨)
<기본문법>
if(a instanceof B) {// => a는 참조변수, B는 클래스 또는 인터페이스)
// a is a B가 성립할때 실행할 코드들.
}
package ref_casting;
public class Ex2 {
public static void main(String[] args) {
SmartPhone2 sp = new SmartPhone2("010-1234-5678", "안드로이드");
// sp는 SmartPhone입니까?? true
if (sp instanceof SmartPhone2) {
System.out.println("sp는 SmartPhone입니다");
} else {
System.out.println("sp는 SmartPhone이 아닙니다");
}
System.out.println("----------------------------------------------------------------------------------------");
//spㅍ는 HandPhone2입니까?? true
if (sp instanceof HandPhone2) {
System.out.println("sp는 HandPhone2입니다");
} else {
System.out.println("sp는 HandPhone2이 아닙니다");
}
System.out.println("----------------------------------------------------------------------------------------");
// hp는 SmartPhone입니까? false
HandPhone2 hp = new HandPhone2("010-1111-2222");
if (hp instanceof SmartPhone2) {
System.out.println("hp는 SmartPhone입니다");
} else {
System.out.println("hp는 SmartPhone이 아닙니다");
}
System.out.println("----------------------------------------------------------------------------------------");
HandPhone2 hp2 = new SmartPhone2("010-1234-5678", "안드로이드");
// hp2는 SmartPhone입니까?? false
if (hp2 instanceof SmartPhone2) {
System.out.println("hp는 SmartPhone입니다");
SmartPhone2 sp2 = (SmartPhone2)hp2;
sp2.call();
sp2.sms();
sp2.kakaoTalk();
} else {
System.out.println("hp는 SmartPhone이 아닙니다");
}
System.out.println("----------------------------------------------------------------------------------------");
// hp2는 SmartPhone입니까?? false
if (hp2 instanceof HandPhone2) {
System.out.println("hp2는 HandPhone2입니다");
} else {
System.out.println("hp2는 HandPhone2이 아닙니다");
}
}
}
class HandPhone2 {
String number;
// 번호없는 폰은 만들기 싫어서 기본 생성자 없앰!!
public HandPhone2(String number) {
this.number = number;
}
public void call() {
System.out.println("전화기능");
}
public void sms() {
System.out.println("문자기능");
}
}
class SmartPhone2 extends HandPhone2 {
String osName;
public SmartPhone2(String number, String osName) {
super(number);
this.osName = osName;
}
public void kakaoTalk() {
System.out.println("카카오톡");
}
}
class Phone {
public void call() {
System.out.println("전화걸기!");
}
}
class HandPhone extends Phone {
public void sms() {
System.out.println("문자 기능");
}
}
class SmartPhone extends HandPhone {
public void kakaoTalk() {
System.out.println("카톡 메시지 전송");
}
}
public class Test1 {
public static void main(String[] args) {
Phone 전화기 = new Phone();
HandPhone 핸드폰 = new HandPhone();
SmartPhone 스마트폰 = new SmartPhone();
Phone 할아버지; // 전화만
HandPhone 아버지; // 전화랑 문자만
SmartPhone 나; // 전부
// 업캐스팅을 해보자.
할아버지 = 스마트폰;
할아버지.call();
아버지 = 스마트폰;
아버지.sms();
// 되는 다운캐스팅을 해보자.
Phone 할아버지1 = new HandPhone();
HandPhone 아버지1;
아버지1 = (HandPhone)할아버지1;
아버지1.call();
아버지1.sms();
Phone 할아버지2= new SmartPhone();
SmartPhone 나1;
나 = (SmartPhone)할아버지;
나.call();
나.kakaoTalk();
}
}
A a = (A)new D(); // 생성자니까 생성자에 있는 ABD 찍힘.
B b = (B)a; // b : a,b 담김. 생성자는 없고, Aa(), Bb() 찍을 수 있따.
A a1 = b; // Aa() 만 찍을 수 있음. ==> 자식은 찍을 수가 없다. 왼쪽 기준으로 왼쪽 까지만 찍을 수 있따.
C c = (C)a1; // down casting.은 바로 생성하는 거 배고는 안된다고 봐야함. 위에 a는 담을 수 있는 이유가 new로 생성했기 때문이다.
-------------------------------------
A a = new F();
C c = (C)a; // down cast - a,c 담을 수 있다. 생성자느 ㄴ없음
H h = (H)a; // down cast - 에러. h는 F의 자식이다. h가 f보다 조상이 아니므로 에러가 난다.
/*
다운캐스팅일 때 되는 것
1. new 해서 바로 생성자를 담을 때
2. 위에서 만든 생성자의 변수를 담을 때
단, 담는 변수가 오른쪽의 실제 담긴 값보다 조상이어야 한다.
*/
'자바스프링웹공부(2024) > 자바' 카테고리의 다른 글
2024.09.20. 추상클래스, 추상메서드, final, block (1) | 2024.09.23 |
---|---|
2024.09.19. 형변환 polymorphism (1) | 2024.09.23 |
2024.09.13. super (0) | 2024.09.16 |
2024.09.10. 상속, 오버라이드,접근제한자 (0) | 2024.09.10 |
2024.09.09.조건문 반복문 연습 (0) | 2024.09.09 |