IT 꿈나무의 일상

Class의 형변환 (Upcasting, Downcasting) 본문

자바

Class의 형변환 (Upcasting, Downcasting)

viera 2020. 7. 16. 19:17
반응형

자바는 객체지향언어(OOP)의 한 종류입니다.

OOP는 객체의 관점에서 프로그래밍 하는 것을 의미합니다.

자바뿐만 아니라 C++, 파이썬, Swift 등 요즘 뜨는 언어들에서 OOP개념을 사용 중입니다.

 

 

OOP의 주요 특징은 다음과 같습니다.

1) 다형성 (Polimorphysm)

2) 캡슐화 (Information hiding, Encapsulation)
3) 상속 (Inheritance)

 

이번 시간에는 이 중 상속(Inheritance) 개념에 관해 말하고자 합니다.

 

상속에 대해 말하기 위해서는 형변환을 설명해야 합니다.

형변환은 클래스 사이에서 일어나는데 자바의 상속 관계에 있는 부모와 자식 클래스 간에는 서로 형변환이 가능합니다.

자바에서는 up casting과 down casting 두가지 종류가 있습니다.

 

 

1. upcasting

upcasting은 서브타입의 인스턴스를 수퍼타입의 변수로 접근하는 것을 말합니다.

즉, 자식 클래스가 부모 클래스 타입으로 캐스팅 되는것을 뜻합니다.

이때 서브 타입에서는 수퍼타입에 선언된 필드 혹은 메서드만 접근 가능합니다.

 

upcasting의 특징은 서브타입을 수퍼타입의 변수에 할당하면 자동으로 형변환이 된다는 점입니다.

예를 들면 Animal --> Birds --> Eagle 순으로 상속을 받을 때 

birds를 상위 클래스인 Animal로 할당이 가능합니다.

 

 

2. down casting

downcasting은 서브타입 인스턴스를 참조하는 수퍼타입 변수를 재참조하는 것을 말합니다.

즉, 부모 클래스가 자식클래스 타입으로 캐스팅되는 것을 뜻합니다.

이때 강제형변환이 일어나며, 다운캐스팅한 타입에서 선언된 모든 필드와 메서드에 접근이 가능합니다.

downcasting에는 주의해야 할점이 있는데, 이는 아래 예제를 보며 설명하도록 하겠습니다.

 

수퍼타입클래스 : 부모클래스를 상속
서브타입클래스 : 부모로부터 상속받은 하위클래스 

 

3. 예제

 

1) 상위 클래스인 Animal 클래스를 만듭니다.

public class Animal {
	public String toString() {
		return "Animal 입니다";
	}
}

 

 

2) Animal을 상속 받는 Birds 클래스를 만듭니다.

- 자바에서는 클래스 이름뒤에 extends + 상속받을 클래스이름을 사용하여 상속을 받습니다.

public class Birds extends Animal{
	public String toString() {
		return "Birds 입니다";
	}
}

 

3) 마지막으로 Birds를 상속 받는 Eagle 클래스를 만듭니다.

public class Eagle extends Birds{
	public String toString() {
		return "Eagle 입니다";
	}

}

 

4) 클래스들의 UML Diagram을 이용하면 다음과 같이 클래스 간의 관계를 한눈에 볼 수 있습니다.

 

5)  이제 클래스간 형변환이 되는지 확인해 보겠습니다

 

- AnimalTest.java 라는 메인메소드를 가진 파일을 하나 생성하겠습니다.

public class AnimalTest {
	
	public static void main(String[] args) {
    
    	//01. upcasting
        
		Birds b = new Birds();    //birds 객체생성
		System.out.println(b);    //객체 확인, 결과 : Bird 입니다
		
		Animal a = b;             //birds를 Animal타입으로 upcasting (자동형변환)
		System.out.println(a);    //결과 : Bird 입니다
		
        //02. downcasting
        
		Birds b2 = (Birds) a;     //upcasting한 a를 다시 birds로 downcasting
		System.out.println(b2);   //downcasting은 명시적형변환이 필요하다.
		                          //결과 : Bird 입니다
                                  
        //03. downcasting 실패하는 경우
        
		if(b2 instanceof Eagle) { //b2가 Eagle의 인스턴스인지 확인하는 코드
		Eagle e = (Eagle) b2;     //b2를 Eagle로 downcasting (명시적형변환)
		System.out.println(e);    
		}else {
			System.out.println("다운캐스팅 불가");  //결과 : "다운캐스팅 불가"
		}

마지막에 downcasting에 실패한 이유는 모든 birds = eagle이 성립하지 않기 때문입니다.

 

 

예제 하나를 더 살펴보겠습니다.

- Cat.java 파일을 하나 더 생성하겠습니다.

 

public class Cat extends Animal{
	public String toString() {
		return "Cat 입니다";
		
	}
}

- Cat.java 파일을 추가한 UML구성도는 다음과 같습니다

 

 

 

- AnimalTest.java 파일에 위의 파일 관련된 코드를 추가해보겠습니다.

 

public class AnimalTest {
	public static void main(String[] args) {
    
		Cat c1 = new Cat();      //cat 타입의 인스턴스생성
		Animal a3 = c1;          //cat을 Animal 타입으로 업캐스팅
		System.out.println(a3);  //결과 : Cat 입니다
		
		Birds b4 = (Birds) a3;  //업캐스팅한 a3을 다시 Birds타입으로 downcasting
		System.out.println(b4); //결과 : error
        }

Cat을 상위 클래스인 Animal로 업캐스팅하는건 가능하지만,

업캐스팅된 변수를 다시 상관없는 Birds타입으로 다운캐스팅하는것은 에러가 나는것을 확인할 수 있습니다.

 

- 에러에 대한 상황에 대처하기 위해 코드를 변경시켜 보겠습니다.

 

 

public class AnimalTest {
	public static void main(String[] args) {
    
		Cat c1 = new Cat();         //cat 타입의 인스턴스생성
		Animal a3 = c1;             //cat을 Animal 타입으로 업캐스팅
		System.out.println(a3);     //결과 : Cat 입니다
		
		if (a3 instanceof Birds) {  
		Birds b4 = (Birds) a3;      
		System.out.println(b4);
		} else {                    //예외상황시 
			System.out.println("Cat은 Bird가 아니다);
		}							//결과 : Cat은 Bird가 아니다

 

 

 

 

 

 

반응형
Comments