up-casting & down-casting

kudos·2021년 5월 12일
1

Java

목록 보기
1/3

1. 개요

1) 정의

up-casting : supertype으로의 casting. 즉, child class type의 객체를 parent class type의 객체로 다룰 수 있게 하는 것.
down-casting : subtype으로의 casting. 즉, upcasting 된 객체를 다시 child class type의 객체로 다룰 수 있게 하는 것.

2) 유의할 점

casting은 객체 자체를 바꾸는 것이 아니라 label을 다르게 붙이는 것 뿐이다. 예를 들어, Dog 객체를 만들고 이를 Animal 객체로 upcasting 했다고 해도 그 객체는 여전히 Dog 객체이다. 다만 그 객체는 이제 다른 Animal 객체와 같은 방식으로 다뤄지고 Dog property들은 숨겨지게 된다.
이렇게 하는 이유는, Animal 객체 group이 있을 때 어떤 동물이 meow()를 할지, bark()를 할지 알 수 없기 때문에 Animal 객체에서는 Child class의 property나 method에 접근할 수 없도록 하는 것이다.

3) 차이점

upcasting은 항상 허용되는 반면, downcasting은 type check를 필요로 하고 ClassCastException을 throw 할 수 있다.

upcasting

upcasting이 안전하다는 것은, 항상 Dog 객체를 Animal 객체로 casting 할 수 있고 Animal의 모든 property와 method를 사용 가능하다는 것을 의미한다.

downcasting

downcasting에서 하는 것은, 프로그램에게 객체의 runtime type이 실제로는 무엇인지 말해주는 것이다. downcasting이 잠재적으로 안전하지 않은 이유는 child class의 method나 property 중 실제로 implement하지 않은 것을 사용하려고 할 수 있기 때문이다. 이는 아래 예시에서 확인할 수 있다.

downcasting 방법

Animal animal = new Animal();
Dog dog = animal;

이 코드는 compile time error를 발생시킨다. 이는 Parent class의 객체가 child class의 객체로 downcast 될 방법이 명시되어 있지 않기 때문이다.

Animal animal = new Animal();
Dog dog = (Dog) animal;

여기서는 compile time error가 발생하지는 않지만 runtime에 ClassCastException이 발생한다. animal의 runtime type이 Animal이기 때문에 runtime에 casting을 하려고 하면, animal은 Dog가 아니기 때문에(animal is not a Dog) ClassCastException이 발생한다.

Animal animal = new Dog();
Dog dog = animal;

여기서는 다시 compile time error가 발생한다. Animal을 Dog로 casting하는 방법을 명시해주지 않았기 때문이다.

Animal animal = new Dog();
Dog dog = (Dog) animal;

이 코드가 제대로 downcasting을 하는 방법이다.

2. 예시

public class Animal {
    public void walk()
    {
        System.out.println("Walking Animal");
    }
}
class Dog extends Animal {  
    public void walk()
    {
        System.out.println("Walking Dog");
    }
    public void sleep()
    {
        System.out.println("Sleeping Dog");
    }
}
class Demo {    
    public static void main (String [] args) {  	
    	Animal a = new Animal();
    	Dog d = new Dog();             
    	a.walk();
    	d.walk();
    	d.sleep();
    	
    	//upcasting  
        Animal a2 = (Animal)d;
        a2.walk();
        //a2.sleep();  error
        
        //downcasting
        Animal a3 = new Dog();
        //Dog d2 = a3;  //compile time error
        Dog d2 = (Dog)a3;
        d2.walk();
        d2.sleep();
        
        //Run time error: Animal cannot be cast to Dog
        Animal a4 = new Animal();
        //Dog d3 = (Dog)a4;
        //d3.walk();
        //d3.sleep();
    }
}

Output

Walking Animal
Walking Dog
Sleeping Dog
Walking Dog
Walking Dog
Sleeping Dog

3. Parent p = new Child()를 사용하는 이유

1) 장점

upcasting을 사용하는 이유는 다형성 때문이다. 어떤 객체의 정확한 runtime type을 알 수 없는 경우에, 이를 이용할 수 있다. 이는 Parent 참조 변수가 어떤 child class 객체든 가지고 있을 수 있기 때문이다.

2) 예시

class Parent {
	void work(){
		System.out.println("working");
	}
}
class Child1 extends Parent{
	void relax(){
		System.out.println("relaxing 1");
	}
}
class Child2 extends Parent{
	void relax(){
		System.out.println("relaxing 2");
	}
}
class Child3 extends Parent{
	void relax(){
		System.out.println("relaxing 3");
	}
}
class Child4 extends Parent{
	void relax(){
		System.out.println("relaxing 4");
	}
}
public class Demo {    
    public static void main (String [] args) {
    	List<Parent> lst = new ArrayList<Parent>();
    	lst.add(new Child1());
    	lst.add(new Child2());
    	lst.add(new Child3());
    	lst.add(new Child4());
    	
    	for(Parent p:lst){    		
    		p.work();
    	}
    	
    	Child1 c1 = (Child1)lst.get(0);
    	c1.relax();
    	
    	Parent parent = getChild("2");
    	parent.work();
    }
    
    public static Parent getChild(String childName){
    	Parent p = null;
    	if(childName.equals("1")){
    		p = new Child1();
    	} else if (childName.equals("2")){
    		p = new Child2();
    	} .......
    	
    	return p;
    }
}

Output

working
working
working
working
relaxing 1
working
profile
kudos

0개의 댓글

관련 채용 정보