1. 자동 타입 변환
클래스에서도 기본 타입들과 마찬가지로 타입 변환이 일어납니다. 클래스의 변환은 상속 관계에 있는 클래스 사이에서 발생합니다. 자식은 부모 타입으로 자동 타입 변환이 가능합니다. 예를 들어 고양이가 동물의 특징과 기능을 상속받았다면 '고양이는 동물이다'가 성립하는 것과 마찬가지입니다.
Cat cat = new Cat();
Animal animal = cat; // Animal animal = new Cat()도 가능.
이 때 cat과 animal 변수는 타입만 다를 뿐 동일한 Cat 객체를 참조합니다. cat == animal // true
또한 바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있습니다.
***부모타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드에만 접근이 가능합니다. 비록 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스로 한정됩니다. 그러나 예외가 있는데, 메소드가 자식 클래스에서 재정의 되었다면 자식 클래스의 메소드가 대신 호출됩니다. 이것은 다형성과 연결됩니다.
Child child = new Child();
Parent parent = child;
parent.method1(); // method1이 부모 클래스의 메소드라면 사용 가능.
parent.method2(); // 부모 클래스의 method2()가 자식 클래스에서 재정의 되었다면 자식 클래스의 메소드 불러옴.
parent.method3(); // method3가 자식 클래스의 메소드라면 사용 불가능.
자동 타입 변환이 필요한 이유는 다형성을 구성하기 위함입니다. 필드의 타입을 부모로 선언하면 다양한 자식 객체들이 저장될 수 있기 때문에 필드 사용 결과가 다양해질 수 있습니다. 이것이 필드의 다형성입니다.
예를 들어 자동차 객체에 4개의 타이어 객체가 있고, 오른쪽 앞의 타이어를 타이어 객체의 자식 객체인 금호 타이어 객체로 교체한다고 할 때, 자동 타입 변환을 사용하면 금호 타이어는 부모 클래스의 멤버를 물려받으면서도 새롭게 재정의한 메소드를 통하여 문제점을 개선할 수 있다.
--------------------------------------------
2. 매개변수의 다형성
자동 타입 변환은 필드에 값을 대입할 때도 쓰이지만, 주로 메소드를 호출할 때 많이 쓰입니다. 메소드를 호출할 때에는 매개 변수의 타입과 동일한 매갯값을 지정하는 것이 정석이지만, 매갯값을 다양화하기 위해 매개변수에 자식 객체를 지정할 수도 있습니다.
예:
class Driver {
void drive(Vehicle vehicle){
vehicle.run();
}
}
****이 예시에서 매개변수의 자리에는 Vehicle 클래스의 자식 클래스들도 자동 타입 변환을 통해 들어올 수 있습니다. 우리는 여기서 매우 중요한 사실을 하나 알 수 있습니다. 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체뿐만 아니라 자식 객체까지도 매갯값으로 사용할 수 있다는 것입니다. 즉, 매개값으로 어떤 자식 객체가 제공되느냐에 따라 메소드의 실행 결과는 다양해질 수 있습니다. 메소드 재정의를 통해 같은 이름의 메소드가 서로 다른 기능을 할 수 있기 때문입니다.
3. 강제 타입 변환
강제 타입 변환(casting)은 부모 타입을 자식 타입으로 변환하는 것을 말합니다. 그렇다고 해서 모든 부모 타입을 자식 타입으로 강제 변환할 수 있는 것은 아닙니다. 자식 타입이 부모 타입으로 자동 변환한 후 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있습니다.
Parent parent = new Child(); // 자동 타입 변환
Child child = (Child) parent; // 강제 타입 변환
자식 타입이 부모 타입으로 자동 타입 변환하면, 부모 클래스에 선언된 멤버만 사용이 가능하다는 제약이 따릅니다. 만약 자식에게 선언된 멤버를 꼭 사용해야 한다면 강제 타입 변환을 통해 다시 자식 타입으로 변환한 다음 자식의 멤버를 사용하면 됩니다.
강제 타입 변환은 자식 타입이 부모 타입으로 변환되어 있는 상태에서만 가능하기 때문에 처음부터 부모 타입으로 생성된 객체는 자식 타입으로 변환할 수 없습니다. 그러므로 부모 변수가 참조하는 객체가 부모 객체인지 자식 객체인지 확인하기 위해서 'instanceof' 연산자를 사용합니다.
boolean result = 좌항(객체) instanceof 우항(타입)
좌항의 객체가 우항의 인스턴스이면, 즉 우항의 타입으로 객체가 생성되었다면 true를 리턴하고 그렇지 않으면 false를 리턴합니다.
public void method(Parent parent) {
if(parent instanceof Child) {
Child child = (Child) parent;
}
}
이런 식으로 강제 타입 변환이 필요한 경우에 istanceof 연산자를 통해 안전하게 변환이 가능합니다. 만약 타입을 확인하지 않고 강제 타입 변환을 시도하면 ClassCastException이 발생할 수 있습니다.
정리:
다형성이란 객체 사용방법은 동일하지만 실행결과가 다양하게 나오는 성질을 말합니다. 다형성을 구현하는 기술에는 메소드 재정의와 타입 변환이 있습니다. 자식 객체가 재정의된 메소드를 가지고 있을 경우, 부모 타입으로 자동 타입 변환 후에 메소드를 호출하면 재정의된 자식 메소드가 호출되면서 다양한 실행결과를 가져올 수 있습니다.
'java' 카테고리의 다른 글
java 인터페이스(interface) (0) | 2021.01.25 |
---|---|
추상 클래스, 추상 메소드 (0) | 2021.01.25 |
메소드 재정의(오버라이딩 Overriding) (0) | 2021.01.24 |
상속과 super(); + this() (0) | 2021.01.24 |
java 이클립스 단축키 모음 (0) | 2021.01.24 |