IT/JAVA

자바 - 다형성(Polymorphism)

트레비라임 2020. 11. 20.

다형성의 개념

다형성은 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다

코드 측면에서 보면 다형성은 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.

Animal클래스를 상속받아서 Human,Tiger,Eagle클래스를 생성하고

Animal클래스에 있는 move()메소드를 오버라이딩 했다

부모클래스의 변수에 넣었지만, 필드나 메소드가 작동하는 것은 new뒤에 붙은 자식클래스의 객체의 본질이다.

 

hAnimal.move()는 부모클래스에 move()메소드가 있기 때문에 실행됨

그러나 hAnimal.readBooks는 부모클래스에 없으므로 오류 발생

 

부모타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다.

비록 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스 멤버로만 한정된다.

그러나 예외가 있는데. 메소드가 자식클해스에서 오버라이딩 되었다면 자식 클래스의 메소드가 대신 호출된다.

이것은 다형성과 관련이 있기 때문에 매우 중요한 성질이므로 잘알아두어야 한다.

부모클래스에 method1,2선언

Parent클래스를 상속받고 자식 클래스에 method2를 오버라이딩하고 method3을 선언한다.

Child객체는 method3() 메소드를 가지고 있지만, Parent타입으로 변환된 이후에는 method3()을 호출할 수 없다. 그러나 method2() 메소드는 부모와 자식 모두에게 있다. 이렇게 오버라이딩된 메소드타입 변환 이후에자식 메소드가 호출된다.

method3은 호출불가능하다. 부모클래스에 없기 때문이다.

 

필드의 다형성

그렇다면 왜 자동 타입 변환이 필요할까? 그냥 자식 타입으로 사용하면 될 것을 부모타입으로 변환해서 사용하는 이유가 무엇일까? 

그것은 다형성을 구현하는 기술적 방법 때문이다. 다형성이란 동할한 타입을 사용하지만 다양한 결과가 나오는 성질을 말한다.  주로 필드의 값을 다양화함으로써 실행 결과가 다르게 나오도록 구현하는데, 필드의 타입은 변함이 없지만, 실행도중에 어떤 객체를 필드로 저장하느냐에 따라 실행 결과가 달라질 수 있다.

프로그램은 수많은 객체들이 서로 연결되고 각자의 역할을 하게 되는데, 이 객체들은 다른 객체로 교체될 수 있어야 한다. 

예를들어 자동차 클래스에 포함된 타이어 클래스를 생각해보자. 자동차클래스를 처름 설계할 때 사용한 타이어 객체는 언제든지 성능이 좋은 다른 타이어(금호 타이어) 객체로 교체할 수 있어야 한다. 이것을 프로그램으로 구현하기 위해서는

상속과 오버라이딩, 그리고 타입 변환을 이용하는 것이다.

 

매개변수의 다형성

자동타입변환은 필드의 값을 대입할 때에도 발생하지만, 주로 메소드를 호출할 때 많이 발생한다.

메소드를 호출할 때에는 매개 변수의 타입과 동일한 매개값을 지정하는 것이 정석이지만, 매개값을 다양화 하기 위해 매개 변수에 자식 타입 객체를 지정할 수도 있다.

Driver 클래스에는 drive()메소드가 정의되어 있는데 Vehicle타입의 매개변수가 선언되어 있다.

참고 : 이것이 자바다 1권

drive()메소드는 Vehicle 타입을 매개 변수로 선언했지만, Vehicle을 상속받은 Bus객체가 매개값으로 사용되면 자동 타입변환이 발생한다. (bus가 Vehicle타입으로 자동 타입 변환이 발생한다.)

우리는 여기서 매우 중요한 것을 하나 알게 되었다. 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체뿐만 아니라 자식 객체까지도 매개값으로 사용할 수있다는 것이다.

매개값으로 어떻 자식 객체가 제공되느냐에 따라 멧드의 실행 결과는 다양해질 수 있다(매개 변수의 다형성)

 

강제 타입 변환(Casting)

강제 타입 변환은 부모 타입을 자식 타입으로 변환하는 것을 말한다. 그렇다고 해서 모든 부모 타입을 자식 클래스 타입으로 강제 변환할 수 있는 것은 아니다.

자식타입이 부모 타입으로 자동 변환한 후, 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있다. 

field2필드와 method3()메소드는 Child 타입에만 선언되어 있으므로 Parent타입으로 자동 타입 변환하면 사용할 수 없다. field2 필드와 method3()메소드를 사용하고 싶다면 타시 Child타입으로 강제 타입 변환을 해야한다.

 

 

객체 타입 확인(instanceof)

hAnimal을 다운캐스팅해서 readBooks를 사용할 수 있게 만들었다.

47번에서 오류가 났다 Human이 Eagle로 캐스팅 될수 없다는 오류다.

이유는 Human 인스턴스인데  Eagle로 강제 캐스팅 하려고 했기 떄문이다.

 

그렇다면 human변수가 참조하는 객체가 부모 객체인지 자식 객체인지 확인하는 방법은 없을까?

어떤 객체가 언떤 클래스의 인스턴스인지 확인하려면 instanceof를 사용하면된다.

boolean result = 좌항(객체) instanceof 우항(타입)

좌항의 객체우항의 인스턴스이면우항의 타입으로 객체가 생성되었다면 ture 아니면false산출한다.

 

instnanceof 연산자는 매개값의 타입을 조사할때 주로 사용된다.

메소드 내에서 강제 타입 변환이 필요한 경우 반드시 매개값이 어떤객체인지 instanceof연산자로 확인하고 안전하게 강제 타입변환을 해야함

하지않으면 ClassCastException 예외가 발생할 수 있다.

 

 

 

'IT > JAVA' 카테고리의 다른 글

자바의 정석 공부 방법  (1) 2020.11.23
자바 - 추상클래스,템플릿 메서드  (0) 2020.11.22
자바 - 메소드 재정의 (오버라이딩 @Override)  (0) 2020.11.20
자바 - 상속(Inheritance)  (0) 2020.11.16
자바 - ArrayList  (0) 2020.11.15

댓글