[JAVA] 객체 형변환

📝 객체 형변환

  • 기본형 변수처럼 참조변수도 형변환(Casting)이 가능하다.
  • 단, 서로 상속 관계에 있는 클래스 사이에서만 가능하다.

Parent parent = new Child();	
  • 위의 대입연산에서 왼쪽 항(부모, Parent)과 오른쪽 항(자식, child)의 객체 유형이
    서로 다른 경우, 두 유형이 서로 상속관계에 있고 왼쪽 객체가 오른쪽 객체의 상위
    클래스인 경우에만 암묵적 형변환이 일어난다.
  • 하위 클래스에서 상위클래스 유형으로 할당하는 것은 가능하나 그 반대의 경우에는
    명시적 형변환을 해야 한다.


📃 암묵적 형변환

  • 자식클래스가 부모클래스에게 상속받은 기능만 사용하도록 제한
  • 주의할 점은 기능의 제한이지 기능의 변경은 아니라는 것이다.
  • 모든 객체는 자신의 상위 형태로 암묵적 형변환이 가능하다.

즉 오버라이드된 기능만 사용가능하고, 추가적으로 구현한 기능은 사용할 수 없다.


암묵적 형변환 가능한 경우

	// 👉 가능하다.
	A a1 = new B();
	A a2 = new X();
	-------------------
	A a3 = new C();
	A a4 = new Y();
	-------------------				
	B b1 = new C();
	X x1 = new Y();
	-------------------
	C c = new C();
	B b2 = c;
	-------------------
	Y y = new Y();
	X x2 = y;
	// ❗❗ 불가능하다.
    C c1 = new B();
    C c2 = new X();

✍ 암묵적 형변환 코드 예시 )

// 부모 클래스
public class Unit {
	private String name;
	
	// 생성자 정의
	public Unit(String name) {
		super(); 
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	// 재정의 대상
	public void attack() {
		System.out.println(this.name + " >>> 공격준비 ");
	}
}
// 자식 클래스

// 육군
public class Army extends Unit {

	// 부모 클래스의 생성자를 강제 호출하기 위한 생성자
	public Army(String name) {
		super(name);
	}
	
	// 공격의 형태를 육군에 맞게 변경하지만,
	// 부모 클래스가 가지고 있는 공격 준비 기능을
	// super 키워드를 통해 보전
	@Override
	public void attack() {
		super.attack();
		System.out.println(super.getName() + " >> 지상공격 실행");
	}
	
	public void tank() {
		System.out.println(super.getName() + " >> 탱크공격");
	}
	
}

// 해군
public class Navy extends Unit{

	public Navy(String name) {
		super(name);
	}

	@Override
	public void attack() {
		super.attack();
		System.out.println(this.getName() + " >> 어뢰발사");
		System.out.println(this.getName() + " >> 지상 상륙");
	}
	
	public void nucleus() {
		System.out.println(this.getName() + " >> 핵미사일");
	}
}

// 공군
public class AirForce extends Unit {

	public AirForce(String name) {
		super(name);
	}

	@Override
	public void attack() {
		super.attack();
		System.out.println(super.getName() + " >> 이륙");
		System.out.println(super.getName() + " >> 공중공격 실행");
	}
	
	public void bombing() {
		System.out.println(this.getName() + " >> 폭격");
	}
}
// Main 클래스
public class Main01 {

	public static void main(String[] args) {
		// army, navy, airforce로 각각의 객체생성
		Army army = new Army("육군");
		Navy navy = new Navy("해군");
		AirForce air = new AirForce("공군");
		
		// 그 각각의 객체의 고유 기능을 사용
		army.tank();
		navy.nucleus();
		air.bombing();
		
		System.out.println("----------------------------------");
		
		// 상위 객체 형태로 암묵적 형변환
		Unit temp1 = army;
		Unit temp2 = navy;
		Unit temp3 = air;
		
		// 형변환이 되더라도 상속받거나 재정의한(Override)
		// 자신들의 기본 특성들은 그대로 유지
		temp1.attack();
		System.out.println();
		temp2.attack();
		System.out.println();
		temp3.attack();
		
		// 상위 클래스 형태로 형변환이 되면, 자신들의 독립 기능은
		// 사용하지 못한다.
//		temp1.tank();
//		temp2.nucleus();
//		temp3.bombing();
		
	}

}

👉 실행 결과

육군 >> 탱크공격
해군 >> 핵미사일
공군 >> 폭격
----------------------------------
육군 >>> 공격준비 
육군 >> 지상공격 실행

해군 >>> 공격준비 
해군 >> 어뢰발사
해군 >> 지상 상륙

공군 >>> 공격준비 
공군 >> 이륙
공군 >> 공중공격 실행

📙 암묵적 형변환 정리

객체가 상위클래스의 형태로 형변환 되더라도 Override된 자신의 기능은 잃지 않는다.
하지만, 추가적으로 구현한 기능은 사용할 수 없다.



📃 명시적 형변환

  • 부모 클래스의 객체를 자식 클래스 형태로 변환하는 것
  • 형변환을 위해서는 다음과 같이 변환할 클래스 이름을 명시적으로 지정해 주어야 한다.
ChildClass child = (ChildClass)parent;

❗❗ 객체가 최초로 생성될 때 자식 클래스 형태로 생성되고, 부모 형태로 암묵적 형변환이 된 상태를
다시 원래의 자식 클래스 형태로 되돌릴 경우에만 가능해진다.

ChildClass child1 = new ChildClass();
ParentClass parent = child1;		// 암묵적 형변환
ChildClass child2 = (ChildClass)parent;	// 명시적 형변환

명시적 형변환 가능한 경우


✍ 명시적 형변환 코드 예시 )

public class Main01 {

	public static void main(String[] args) {
		// army, navy, airforce로 각각의 객체생성
		Army army = new Army("육군");
		Navy navy = new Navy("해군");
		AirForce air = new AirForce("공군");
		
		System.out.println("----------------------------------");
		
		// 상위 객체 형태로 암묵적 형변환
		Unit temp1 = army;
		Unit temp2 = navy;
		Unit temp3 = air;
		
		temp1.attack();
		System.out.println();
		temp2.attack();
		System.out.println();
		temp3.attack();
		
		System.out.println("----------------------------------");
 
		// 하위 클래스 형태로 명시적 형변환
		Army re1 = (Army)temp1;
		Navy re2 = (Navy)temp2;
		AirForce re3 = (AirForce)temp3;
		
		re1.tank();
		re2.nucleus();
		re3.bombing();
		
	}

}

👉 실행 결과

육군 >>> 공격준비 
육군 >> 지상공격 실행

해군 >>> 공격준비 
해군 >> 어뢰발사
해군 >> 지상 상륙

공군 >>> 공격준비 
공군 >> 이륙
공군 >> 공중공격 실행
----------------------------------
육군 >> 탱크공격
해군 >> 핵미사일
공군 >> 폭격

✍ 명시적 형변환이 불가능한 경우

Unit u = new Unit();
Army army = (Army)u;		// 최초 객체 생성이 부모 형태로 만들어진 경우 불가능하다.
Army army = new Army();
Unit u = army;
Navy navy = (Navy)u;		// 다른클래스로 만들어진 객체에 명시적 형변환은 불가능하다.

📙 암묵적 형변환 정리

하위 클래스 형태로 명시적 형변환을 함으로써, 자신들의 독립 기능(메서드)들을 사용할 수 있다.

좋은 웹페이지 즐겨찾기