JAVA

업 캐스팅(Up Casting)

🤖 Play with Android 🤖 2021. 8. 31. 11:11
728x90


캐스팅(Casting)이란?

캐스팅이란 형변환이라고도 하며 타입을 변환하는 것을 말한다. 자바의 상속관계에 있는 부모와 자식클래스 간에는 서로 형변환이 가능하다.

부모 클래스인 상속 관계의 상위 클래스를 수퍼 클래스, 그리고 자식 클래스인 하위 클래스를 서브 클래스라고 정의한다.

 

 

 

 


 

 

 

업캐스팅(Up Casting)이란?

업 캐스팅이란, 자식 객체를 부모의 타입으로 해석하는 것이다. 예를 들어 아래와 같은 상속 관계가 있을 때,

class Animal { ... }

class Cat extends Animal { ... }
class Dog extends Animal { ... }
class Horse extends Animal { ... }

 

Cat의 인스턴스(객체)는, Animal로 해석 될 수 있다.

// 고양이 객체 생성
Cat c = new Cat();

// 고양이는 동물이다(O)
Animal a = c; // 고양이 객체를 동물로 해석

 

 

하지만 위 내용의 역은 성립하지 않음을 주의해야 한다.

그 이유는 단순하게 생각해서 고양이는 동물이다 라는 명제는 참이 될 수 있지만 동물은 고양이다 라는 명제는 참이 될 수 없다.

// 동물 객체 생성
Animal aaa = new Animal();

// 동물은 고양이다(X)
Cat ccc = aaa; // ERROR!

 

 

업캐스팅을 하게되면 객체 내에 있는 모든 멤버에 접근할 수 없다. 오직 수퍼 클래스의 멤버에만 접근이 가능하다. 이는 멤버 필드(field)뿐만 아니라 메서드(method)에도 동일하게 적용된다.

 

 

이러한 업 캐스팅은, 다양한 객체들을 부모의 타입으로 관리할 수 있게 한다. 이를 그룹화 할 수 있다고 한다.

Animal c = new Cat();   // 고양이는 동물이다
Animal d = new Dog();   // 개는 동물이다
Animal h = new Horse(); // 말은 동물이다

// 동물 배열 - 고양이, 개, 말 -> 그룹화
Animal[] animals = { c, d, h };

 

 


 

 

업 캐스팅을 활용할 수 있는 간단한 예제

출처 - 클라우드스터딩

 

 

 

 

주어진 그림은 Knight 및 Thief 클래스를 정의하고 있다. 두 클래스의 공통 요소를 추출하여 부모 클래스 Adventurer를 작성하는 코드를 만들어보자.

public class UpCasting {
    public static void main(String[] args) {
        Knight knight = new Knight();
        knight.name = "아서스";
        knight.hp = 180;
        knight.strength = 50;

        Thief thief = new Thief();
        thief.name = "발리라";
        thief.hp = 120;
        thief.agility = 40;

        Adventurer adv0 = knight;
        Adventurer adv1 = thief;

        Adventurer[] advs = { adv0, adv1 };

        for (int i = 0; i < advs.length; i++) {
            System.out.println(advs[i].toString());
        }
    }
}

class Adventurer {
    String name;
    int hp;

    public void punch() {
        System.out.printf("[%s]의 펀치!!\n", name);
    }

    public String toString() {
        return String.format("[%s] HP: %d", name, hp);
    }
}

class Knight extends Adventurer{
    int strength;

    public void berserker() {
        System.out.println("체력과 공격력이 증가합니다.");
    }
}

class Thief extends Adventurer{
    int agility;

    public void sharpen() {
        System.out.println("크리티컬 확률이 증가합니다.");
    }
}

 

 

우선 Knight 클래스와 Thief 클래스의 공통 필드와 메소드를 부모클래스인 Adventurer 클래스에 정의해준다. 중복을 제거하기 위해 

Knight 클래스와 Thief 클래스에 있던 공통 필드와 메소드는 없애준다.

Knihgt 객체와 Thief 객체를 만들어 주어 각각 초기화 시켜준 다음 그 두 객체를 Adventurer 형으로 업캐스팅 해준다.

그러면 이제 Adventurer[ ] advs 배열에 저장할 수 있게 된다. (각 다른 객체를 하나의 형태의 배열로 저장할 수 있게된다.)