티스토리 뷰

타입 형 변환

int x = (int) 10.0;

대입 연산자를 기준으로 오른쪽 값을 왼쪽 값에 맞추는 것이 기본 규칙이다.
10.0의 기본 타입은 double인데 왼쪽 타입이 int 이므로 캐스팅을 통해 타입을 맞춰주게 된다.

이 타입 형변환을 객체간에서도 구현해줄 수 있다.

 

Strongly typed language

자바는 데이터 타입을 미리 정의해서 사용하고 한 번 정의된 데이터 타입은 프로그램 종료까지 변하지 않는 강한 타입의 언어이다.

프로그램 개발에 있어서 명확함과 구체성을 제공한다는 장점과 유연성이 제약된다는 단점이 있다.

 

여기에 대한 예외가 하나 존재하는데 그것이 객체간 타입 형변환을 가능하게 하는 지점이다.

 

객체간 타입 형변환

상속 관계에서 자식 클래스가 부모 클래스 타입으로 참조되는 것이 허용되는데 이를 up-casting 이라고 한다.

또한, 부모 클래스 타입으로 참조가 이루어진 이후 다시 자식 클래스로 참조하는 것을 down-casting 이라고 한다.

public class FruitStore {
    public static void main(String[] args) {
        Fruit fruit = new Mango();  // 업 캐스팅

        Mango mango = (Mango) fruit;  // 다운 캐스팅

        Apple apple = new Fruit(); // X, 업캐스팅이 먼저 되어야 함
    }
}

상속 관계에서 자식 클래스의 인스턴스가 부모 클래스의 변수로 참조되면(업캐스팅) 실제 인스턴스화 객체가 자식 객체일 경우에도 자식 클래스가 가지고 있는 메소드를 호출 하려면 다운 캐스팅이 이루어져야 한다.

단, 재정의하고 있는 메소드는 업캐스팅 상황에서도 자식 클래스의 재정의 메소드가 호출된다.

public class Mango extends Fruit {
    @Override
    public void fruitMethod() {
        System.out.println("Mango!")
    }

    public void mangoMethod() {
        // ....
    }
}

Fruit fruit = new Mango();
fruit.mangoMethod();  // (X: 자식 객체 메소드에 접근하려면 다운 캐스팅이 되어야 함)

Mango mango = (Mango) fruit;
mango.fruitMethod();  // (O)

mango.mangoMethod();  // Mango!

 

메모리 흐름

class Fruit {
    String type;

    public String getType() {
        return this.type;
    }

    public void wash() {
        System.out.println("Fruit wash!");
    }
}

class Mango extends Fruit {
    int price;

    public int getPrice() {
        return this.price;
    }

    @Override
    public void wash() {
        System.out.println("Mango wash!");
    }
}

public class FruitStore {
    public static void main(String[] args) {
        Fruit fruit = new Mango(1000);
        fruit.getType();
        fruit.wash();
    }
}

 

Fruit Fruit = new Mango(1000);

위와 같이 업캐스팅을 하면, 먼저 Mango 클래스가 상속받고 있는 부모 클래스인 Fruit의 인스턴스 객체가 먼저 만들어지고 Mango가 인스턴스화 된다.

이 때 Fruit과 Mango는 타입이 다르므로 인스턴스화된 부모 객체의 메소드에만 접근이 가능하다.

fruit.type();  // O
fruit.price();  // X

그러나 오버라이딩된 메소드는 부모가 가지고 있는 메소드를 자식 메소드가 덮어쓰기 때문에 자식 객체의 오버라이딩 메소드가 호출된다!

fruit.wash();  // Mango wash!

 

업캐스팅 다운캐스팅의 이점

Collection은 같은 타입끼리만 묶어서 관리를 할 수가 있다. 업캐스팅을 하면 자식 클래스가 부모 클래스 타입의 변수로 참조가 가능하기 때문에 같은 부모 클래스를 상속하는 모든 자식 클래스들을 하나의 타입으로 관리할 수가 있다.

결과적으로 프로그램의 복잡성을 줄일 수 있다!

 

다형성(polymophism)

다형성이란 하나의 객체가 다양한 형태로 처리될 수 있는 특성을 의미한다.

Fruits[] fruits = new Fruits[3];
fruits[0] = new Apple(1000);
fruits[1] = new Mango(2000);
fruits[2] = new Banana(3000);

for (Fruits fruit : fruits) {
    fruit.wash();
}

// Apple wash!
// Mango wash!
// Banana wash!

위와 같이 fruit.wash() 라는 같은 메소드를 호출하였는데 각각 다른 형태로 처리가 된다.

 

다형성 구현을 위해서는 상속, 메소드 재정의, 객체간의 형변환 이라는 세 가지 조건이 필요하다!

 

다형성 구현 방식

public class FruitStore {
    public static void main(String[] args) {
        washFruit(new Apple(1000));
        washFruit(new Mango(2000));
        washFruit(new Banana(3000));
    }

    public static void washFruit(Fruit fruit) {
        fruit.wash();
    }
}

파라미터를 통해 다형성을 구현하는 방식으로 메소드의 파라미터를 부모 클래스 타입으로 하고, 메소드를 호출할 때 인스턴스를 자식 객체로 만들어서 보낸다!

 


참고 자료

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함