티스토리 뷰
2. 객체의 형변환
1. 형변환 개요
- 작은 데이터 타입 ----묵시적 형변환 (Promotion)-------> 큰 데이터 타입
- 데이터 손실x 자동 캐스팅
- 작은 데이터 타입 <----명시적 형변환 (Demotion)------- 큰 데이터 타입
- 데이터 손실 가능성 - 명시적 캐스팅
// 묵시적 형변환 (자동)
int age = 25;
double avgAge = age; // 형변환 연산자 (double) 생략
// 25.0
// 명시적 형변환
double avgAge = 24.56;
int age = (int)avgAge' // 24 출력
객체 형변환(Casting)의 개요
객체 참조변수들 간의 대입 규칙
leftObjRef = rightObjRef
부모 클래스 = 자식 클래스
- 왼쪽 항과 오른쪽 항의 객체 유형이 서로 다른 경우 두 유형이 서로 상식 관계에 있음
- 왼쪽 객체가 상위 클래스 => 묵시적 형변환
- 자식 클래스 -> 부모 클래스 유형으로 할당하는 것 가능, 반대의 경우 명시적 형변환을 해야 함
- 부모 클래스 -> 자식 클래스 형변환 시, 할당되는 인스턴스 유형에 따라 실행 오류 발생
instanceof
연산자 활용- 생성된 객체가 class와 관계있는 형(type)으로 만들어졌는지 확인
- true 또는 false 값을 반환
class Employee {
}
class Manager extends Employee {
}
public class InstanceOfTest {
public static void main(String[] args) {
Manager m = new Manager();
Employee e = new Employee();
System.out.println(m instanceof Manager); // true
System.out.println(m instanceof Employee); // true
System.out.println(e instanceof Manager); // false
}
}
객체의 형변환
- 클래스의 형변환은 기본적으로 상속 관계가 아닌 클래스 사이에는 발생하지 않음
- 자식 클래스의 객체는 부모 타입의 참조 변수에 할당될 수 있음 (묵시적 형변환)
class Employee {
String name;
int employeeNo;
int departmentNo;
public String getEmployeeInfo() { ... }
}
class Manager extends Employee {
Employee[] employeeList; // 변수 추가
public String getMangerInfo() { ... } // Overriding
}
1. Employee 객체에 접근할 수 있는 경우
Employee e1 = new Employee();
// e1 참조 변수는 타입이 Employee이고, Employee 객체를 참조함
-
타입과 생성된 객체가 모두 Employee
- Employee 객체가 가지고 있는 변수나 메소드 모두 접근이 가능함
2. Employee, Manager 객체에 모두 접근할 수 있는 묵시적 형변환인 경우
Manager m1 = new Manager();
// m1 참조 변수는 타입이 Manager이고, Manager 객체를 참조함
- 타입과 생성된 객체가 모두 Manager임
- Manager 객체의 멤버 필드와 메서드 모두 접근이 가능함 (묵시적 형변환)
- Manger 클래스는 Employee 클래스로부터 상속받았으므로, 객체 생성시 Manager 객체뿐만 아니라 Employee 객체도 생성
- Manager 객체 생성 시 Employee가 가진 속성이 메모리에 로딩됨
- m1 참조변수를 통해 Employee, Manager 객체의 변수와 메서드를 모두 접근할 수 있음
3. 생성된 객체와 참조하는 변수의 타입이 다른 경우
Employee e2 = new Manager();
// e2 참조 변수는 타입이 Employee이고, Manager 객체를 참조함
- Manager는 Employee를 생성하기 때문에, Employee 객체가 가진 변수와 메서드 모두를 가지고 있는 객체다.
- 생성된 객체는 Manager이지만 참조 변수의 타입이 Employee => 접근 가능한 변수와 메소드는 Employee 객체로 제한됨
4. Employee, Manger 객체에 모두 접근할 수 있는 명시적 형변환인
Manager m2 = (Manager)e2;
// m2 참조 변수는 타입이 Manager이고, Manager 객체를 참조함
- Employee 형의 e2 참조 변수를 Manager 형으로 명시적 형변환을 하고 있음
- m2는 Manager 타입이므로 e2가 참조하고 있던 Manager 객체의 모든 멤버 필드와 메서드에 접근이 가능함
// TV 클래스를 추상 클래스로 정의한다.
abstract class TV {
public abstract void powerOn();
public abstract void powerOff();
public abstract void volumeUp();
public abstract void volumeDown();
}
// TV 클래스를 상속하여 S_TV 클래스 정의 => Overriding 필요
class S_TV extends TV {
public void powerOn() {
System.out.println("S_TV --- 전원을 켠다.");
}
public void powerOff() {
System.out.println("S_TV --- 전원을 끈다.");
}
public void volumeUp() {
System.out.println("S_TV --- 소리를 높인다.");
}
public void volumeDown() {
System.out.println("S_TV --- 소리를 낮춘다.");
}
}
//TV 클래스를 상속하여 L_TV 클래스 정의 => Overriding 필요
class L_TV extends TV {
public void powerOn() {
System.out.println("L_TV --- 전원을 켠다.");
}
public void powerOff() {
System.out.println("L_TV --- 전원을 끈다.");
}
public void volumeUp() {
System.out.println("L_TV --- 소리를 높인다.");
}
public void volumeDown() {
System.out.println("L_TV --- 소리를 낮춘다.");
}
}
//TV 객체를 생성하여 리턴하는 TVFactory 클래스 작성
class TVFactory {
// 모든 TV 객체들은 TV 타입으로 묵시적 형변환되어 리턴됨
public TV getTV(String tvName) {
if(tvName.equals("A사")) {
return new S_TV();
} else if(tvName.equals("B사")) {
return new L_TV();
}
return null;
}
}
public class AbstractTVUser {
public static void main(String[] args) {
TVFactory factory = new TVFactory();
TV tv = factory.getTV(args[0]);
// 명령형 매개변수가 무엇인지에 따라 다른 TV 객체가 실행됨
tv.powerOn();
tv.volumeUp();
tv.volumeDown();
tv.powerOff();
}
}
2. 형변환과 멤버
- 형변환에 참여한 서로 상속 관계에 있는 두 클래스 간에는 동일한 이름의 변수가 존재하거나 메서드가 Overriding 되어 있을 수 있음
- 생성된 객체 변수를 통해 멤버에 접근할 때 주의해야 함
- 객체 참조 변수가 변수나 메서드를 참조하는 경우, 참조 관계를 결정하는 시간이 다르기 때문에 차이가 발생
class Parent {
int num = 10;
void printNum() {
System.out.println(num);
}
}
class Child extends Parent {
int num = 20;
void printNum() {
System.out.println(num);
}
}
public class ObjectCastTest {
public static void main(String args[]) {
// Parent 클래스의 객체 생성 및 요소 접근
Parent p = new Parent();
p.printNum(); // 10
System.out.println(p.num); // 10
// Child 클래스의 객체 생성 및 요소 접근
Child c = new Child();
c.printNum(); // 20
System.out.println(c.num); // 20
// 묵시적 형변환을 하는 경우
Parent p2 = new Child(); // Child 객체 생성, Parent 타입 변수에 할당
p2.printNum(); // 20 - Child 객체에서 Overriding된 메서드 호출
// 2. 메서드 호출은 할당되는 인스턴스에 의해 결정됨
System.out.println(p2.num); // 10
// 1.변수에 대한 접근은 객체의 유형에 의해 결정됨
}
}
출처 - swexpertacademy.com/
'Java > Java Basic' 카테고리의 다른 글
[Java] 2-07 - 자바 패키지 (0) | 2021.01.11 |
---|---|
[Java] 2-07 - 인터페이스 (0) | 2021.01.11 |
[Java] 2-06 - 추상 클래스 (0) | 2021.01.10 |
[Java] 2-05 - 자바의 상속, super, final (0) | 2021.01.10 |
[Java] 2-04 - 매개변수 - 값 복사, 주소 복사, Call by value, Call by reference (0) | 2021.01.09 |
댓글