지구정복
[JAVA] 타입변환과 다형성 본문
다형성은 사용방법은 동일하지만 다양한 객체를 이용해서 다양한 실행결과가 나오도록 하는 성질이다.
다형성을 구현하려면 메소드 재정의와 타입 변환이 필요하다.
자식 클래스들은 동일한 부모 클래스를 상속해서 기능은 같지만 성능은 다르다.
ㅁ자동 타입 변환
타입 변환은 타입을 다른 타입으로 변환하는 행위를 말한다.
클래스의 변환은 상속 관계에 있는 클래스들 사이에서 발생한다.
자식은 부모 타입으로 자동 타입 변환이 가능하다.
이때 자동 타입 변환은 프로그램 실행 도중에 자동적으로 타입 변환이 일어하는 것을 말한다.
자동 타입 변환의 개념은 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있다는 것이다.
또한 부모와 자식 사이에서 자식이 상속받는 부모가 바로 위에 부모가 아니더라도 자동 타입 변환이 가능하다.
부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다.
예외로는 메소드가 자식 클래스에서 재정의되었다면 자식 클래스의 메소드가 대신 실행된다.
아래 예제에서 부모 클래스에서 메소드 2개를 정의한다.
자식 클래스는 부모 클래스를 상속받고 method2()를 재정의한다.
실행 클래스에서 먼저 자식 클래스로부터 객체를 만든 뒤 부모 타입으로 자동 타입 변환 시킨다.
이제 child 객체는 부모 타입이므로 부모의 필드와 메소드만 사용가능하다.
다만 method2()는 자식 클래스에서 재정의되었으므로 재정의된 메소드가 실행된다.
method3()는 자식클래스에서만 정의했으므로 현재 부모 타입에서는 사용 불가하다.
ㅁ필드의 다형성
자동 타입 변환이 필요한 이유는 무엇일까?
바로 다형성을 구현하기 위해서이다.
필드의 타입을 부모 타입으로 선언하면 다양한 자식 객체들이 저장될 수 있기 때문에 필드 사용 결과가 달라질 수 있다.
이것이 필드의 다형성이다.
아래 예제를 보면서 이해하자.
자동차 타이어가 최대 회전수가 되면 펑크가 나서 다른 타이어로 교체해줘야 되는 코드를 작성해보자.
Tire부모 클래스는 타이어의 최대회전수, 누적회전수, 타이어위치를 필드값으로 하고
tire의 수명을 알 수 있는 roll()이라는 메소드를 정의하자.
아래의 Car 클래스는 4개의 타이어 객체를 가지는 클래스이다.
또한 자동차를 달리게하는 run() 메소드와 타이어가 펑크났을 때 멈추는 stop() 메소드를 정의한다.
car 객체를 만들고 car객체의 run() 메소드를 호출해서 자동차를 달리게 한다.
자동차가 달리면 각 타이어의 roll() 메소드가 실행되고 누적회전수가 증가되면서 최대회전수가 되면
펑크가 난다. 펑크가 나면 false 값을 리턴하고 stop() 메소드 실행 및 타이어의 위치값이 리턴된다.
리턴된 타이어의 위치값은 problemLoction 변수에 저장되고 스위치 문을 통해서 새로운 타이어로 교체된다.
새로운 타이어는 타이어의 자식 객체인 금호타이어나 한국타이어로 교체된다.
ㅁ매개변수의 다형성
자동 타입 변환은 메소드를 호출할 때도 많이 발생한다.
메소드를 호출할 때는 매개 변수의 타입과 동일한 매개값을 지정하는 것이 정석이지만
매개값을 다양화하기 위해 매개 변수에 자식 객체를 지정할 수도 있다.
예를 들어 다음과 같이 Driver 클래스에 drive() 메소드가 정의되어 있고 매개 변수 타입이 Vehicle 이라고 하자.
이때 Bus 클래스는 Vehicle 클래스를 상속받는다고 하자.
그럼 drive()메소드에 bus 객체를 집어넣으면 bus는 Vehicle 타입으로 자동 타입 변환된다.
class Driver {
void drive(Vehicle vehicle) {
vehicle.run();
}
}
class Vehicle {
void run() {
System.out.println("차량이 달립니다.");
}
}
class Bus extends Vehicle {
@Override
void run() {
System.out.println("버스가 달립니다.");
}
}
class DriverExample {
public static void main(String[] args) {
Driver driver = new Driver();
Bus bus = new Bus();
driver.drive(bus); //자동 타입 변환
}
}
ㅁ강제 타입 변환
강제 타입 변환은 부모 타입을 자식 타입으로 변환하는 것을 말한다. 다만 자식 타입이 부모 타입으로 자동 타입 변환한 후 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있다.
즉, 아래와 같은 상황이다.
Parent parent = new Child(); //자동 타입 변환
Child child = (Child)parent; //강제 타입 변환
자식 타입이 부모 타입으로 자동 타입 변환되면 부모에 선언된 필드와 메소드만 사용 가능하다는 제약 사항이 따른다.
만약 자식에 선언된 필드와 메소드를 사용하려면 강제 타입 변환을 다시 한다음에 사용할 수 있다.
ㅁ객체 타입 확인
강제 타입 변환은 자식 타입이 부모 타입으로 변환되어 있는 상태에서만 가능하기 때문에 아래 코드와 같이
처음부터 부모 타입으로 생성된 객체는 자식 타입으로 변환할 수 없다.
Parent parent = new Parent();
Child child = (Child) parent; //XXX 강제 타입 변환 불가능
만약 강제 타입이 가능한 지 여부를 알고 싶을 때는 instanceof 연산자를 사용한다. 사용법은 아래와 같다.
boolean result = 좌항(객체) instanceof 우항(타입)
연산자의 좌항에는 객체가 오고 우항에는 타입이 와서 좌항의 객체가 우항의 타입으로 생성되었다면 true,
아니면 false를 리턴한다.
광고타임
출처
혼자공부하는 자바 - 신용권
'데이터 엔지니어링 정복 > JAVA & JSP' 카테고리의 다른 글
[JAVA] 인터페이스 (0) | 2020.11.04 |
---|---|
[JAVA] 추상 클래스 (0) | 2020.11.04 |
[JAVA] 상속 (0) | 2020.10.28 |
[JAVA] 패키지와 접근 제한자 (0) | 2020.10.28 |
[JAVA] 인스턴스 멤버와 정적멤버 (0) | 2020.10.27 |