백_곰 2021. 1. 12. 16:32

1. 객체지향에서의 다형성이란?

(1) '여러 가지 형태를 가질 수 있는 능력'을 의미한다.

 

(2) 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 한다.

 

(3) 즉, 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조할 수 있도록 하였다.

 

 

 

2. 예제(1) - 다형성 구현해보기.

( 여기서 7번째 줄에서 주석으로 달린 것을 사용하면 에러가 발생한다. )

( 그 이유는 인스턴스인 A의 멤버 개수보다 참조변수 b가 사용할 수 있는 멤버 개수가 많기 때문이다.)

 

--> 자손 타입의 참조변수가 조상 타입의 인스턴스를 참조하는 것은 존재하지 않는 멤버를 사용하고자 할 가능성이

있기에 막아놓은 것이다.

 

( 예를 들자면, B b = new B()가 있다고 생각해보자. 그러면 b는 자신의 인스턴인 B에서 멤버 j와 b()를 사용할 수

있다. 그러나, B b = new A()가 있으면, b는 인스턴스인 A를 참조하고 있기에, 인스턴스인 B에서의 멤버 j와 b()를

사용한다고 해도 초기화를 하지 않아 없기 때문에, 막아놓은 것이라고 생각하면 된다.)

 

( 즉, 참조변수 b는 new A()를 통해 생성자 A()부터 super()를 통해 Object 클래스까지만 초기화한다. )

( 그러므로, 자식 클래스를 초기화할 수 없다. )

 

( 항상 조상은 자손의 멤버 갯수보다 항상 같거나 적기 때문에, 형변환이 가능하다. )

 

 

 

3. 참조변수의 형변환

- 참조변수 또한 기본형 변수와 같이 형변환이 가능하다. 

(단, 상속관계에서만 가능하다.)

 

( #형변환이 생략 가능한 것은 업-캐스팅이라고 부른다. )

( #형변환이 생략 불가능한 것은 다운-캐스팅이라고 부른다. )

 

- 업-캐스팅 vs 다운-캐스팅

 

( 주의해야 할 점은 업-캐스팅자동으로 형변환을 해주므로 오류가 없지만, 다운-캐스팅일 경우 

형변환이 자동으로 되지 않는다. 그렇기에 오류가 발생되어 프로그램이 멈출 수 있다. )

 

( 그러므로, 만약 확실하지 않고 컴파일 에러가 발생할 것 같으면, instanceof 연산자를 이용하여 확인한다. )

( 아래의 링크를 통해 다음 장에서 확인해보기. )

 

instanceof 연산자 (tistory.com)

 

instanceof 연산자

1. 사용 방법 - 주로 조건문에서 사용한다. - instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입이 피연산자로 위치한다. - 결과값은 boolean 값인 true 또는 false가 반환된다. - 만약 값이 null인 참조변

kind-coding.tistory.com

 

 

 

- 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에, 참조 변수의

형변환은 인스턴스에 아무런 영향을 주지 않는다.

 

( 그러나, 우리가 형변환을 사용하는 이유는 참조변수의 형변환을 통해서 참조하고 있는 인스턴스에서

사용할 수 있는 멤버의 범위(개수)를 조절할 수 있기 때문이다. )

 

( 조상으로부터 상속 받은 자손이 조상의 메서드를 오버라이딩 한다면, 조상의 참조변수가 형변환을 통해

오버라이딩된 멤버를 사용하는 것처럼 멤버의 범위를 조절한다. )

 

( 아래의 코딩을 보자. )

( 객체 b1의 맴버는 x, y, ss(), rr()이 된다. )

( 객체 b2의 맴버는 x, y, ss(), rr()이 된다. )

 

 

 

4. 예제(2) - 컴파일러를 통한 에러 잡기.

( 이처럼 컴파일은 ok이지만, 실행 시 에러가 발생하게 된다. )

( 그 이유는 자손 타입이 조상 인스턴스를 참조하는 것은 문법에 어긋나기 때문이다. )

 

( 그러나, 애초부터 컴파일이 에러를 표시를 하지 않았을까? )

( 그 이유는 컴파일러는 참조변수간의 타입만 체크할 뿐, 실행 시 생성될 인스턴스의 타입에 대해서는 전혀

알지 못하기 때문이다. )

 

( 그렇기 때문에, 아래의 코드처럼 인스턴스 생성 유무 확인을 위해 항상 체크해야 한다. )