다형성(Polymorphism)
하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.
Overloading과 다형성
오버로딩은 가장 이해하기 쉬운 다형성의 예라고 할 수 있다. 아래의 코드를 살펴보자
클래스 O의 메소드 a는 두개의 본체를 가지고 있으며, 동시에 두개의 본체는 하나의 이름인 a를 공유하고 있다.
같은 이름이지만 서로 다른 동작 방법(매개변수)을 가지고 있기 때문에 오버로딩은 당형성의 한 예라고 할 수 있다.

클래스와 다형성
아래 코드는 클래스 B의 데이터 형이 클래스 A이다. 클래스 B는 클래스 A를 상속하고 있으며, 이런 경우에는 클래스 B는 클래스 A를 데이터 형으로 삼을 수 있다.

아래 코드를 살펴보면 19행에 에러가 발생한다. 즉, object.x();는 실행이 되지만, object.y();는 실행되지 않는다는 것, 클래스 B는 메소드 y를 가지고 있지만 10행은 마치 메소드 y가 없는 것처럼 실행되지 않고 있다는 뜻이다.
클래스 B의 데이터 형을 클래스 A로 하면 클래스 B는 클래스 A인것처럼 동작하게 되는 것이다. 클래스 B를 사용하는 입장에서는 클래스 B를 클래스 A인것처럼 사용하면 된다.

* 클래스 B의 데이터 타입을 클래스 A로 인스턴스화 시켰을 때 클래스 B의 메소드 y는 마치 존재하지 않는 것처럼 실행되지 않음 -> 클래스 B가 클래스 A화 되었다.
아래 코드를 살펴보면 클래스 A의 메소드 x를 클래스 B에서 오버라이딩하고 있다.
object.x(); 를 실행하면 결과는 'B.x'가 나온다.

* 클래스 B의 데이터 타입을 클래스 A로해서 인스턴스화 시켰을 때 클래싀 B의 메소드 x를 실행하면 클래스 A에서 정의된 메소드가 아니라 클래스 B에서 재정의된 메소드가 실행 되었음 -> 클래스 B의 기본적인 성질은 그대로 가지고 있음
위의 내용을 다시 정리하자면 다음과 같다.
클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 시켰을 때 클래스 A에 존재하는 멤버만 클래스 B의 멤버가 된다. 동시에 클래스 B에서 오버라이딩한 멤버의 동작방식은 그대로 유지한다.
아래 코드는 서로 다른 클래스 B와 C가 동일한 데이터 타입 A로 인스턴스화 되었다.
이 코드를 실행시켜보면 두 인스턴스의 메소드 x를 호출한 결과가 서로 다르다.
이것이 상속과 오버라이딩 그리고 형변환을 이용한 다형성이다.

abstract 공부할 때 사용했었던 코드를 이용하여 다형성에 대하여 더 알아보자
https://yelin1217.tistory.com/89
[Java] abstract
abstract abstract는 한국어로는 추상으로 번역되며, 상속을 강제하는 일종의 규제라고 생각하면 된다. abstract 클래스나 메소드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제하는 것이며, a
yelin1217.tistory.com
코드가 달라진 부분은 38행과 42행이다.
Calculator를 상속 받은 클래스들은 인스턴스화 할 때 Calculator를 데이터 타입으로 하고 있다.
이렇게 되면 인스턴스 c1과 c2를 사용하는 입장에서는 두개의 클래스 모두 Calculator인 것처럼 사용할 수 있다.

위의 코드를 조금 더 바꿔서 클래스 CalculatorDemo의 execute 메소드는 CalculatorDemoPlus와 CalculatorDemoMinus 클래스의 메소드 run을 호출하면서 그것이 '실행결과'라는 것을 콘솔창에 표시하는 기능을 가지고 있다.
이 때 메소드 execute 내부에서는 매개변수로 전달된 객체의 메소드 run을 호출하고 있다.

만약 메소드 execute의 매개변수 데이터 타입이 Calculator가 아니라면 위와 같은 로직을 처리할 수 없을 것이다.
메소드 execute 입장에서는 매개변수로 전달된 값이 Calculaotr이거나 그 자식이라면 메소드 run을 가지고 있다는 것을 보장 받을 수 있게 된다.
CalculatorDemo 클래스의 다형성이란 하나의 클래스(Calculaotr)가 다양한 동작 방법(CalculatorDemoPlus와 CalculatorDemoMinus)를 가지고 있는데 이것을 다형성이라고 할 수 있다.
인터페이스와 다형성
특정한 인터페이스를 구현하고 있는 클래스가 있을 때 이 클래스의 데이터 타입으로 인터페이스를 지정할 수 있다.

위의 코드 중 30행과 32행은 오류가 발생한다. 그 이유는 obj2의 데이터 타입이 I2이기 때문이다. 인터페이스 I2는 메소드 A만을 정의하고 있고 I2를 데이터 타입으로 하는 인스턴스는 마치 메소드 A만 가지고 있는 것처럼 동작하기 때문이다. 즉, 데이터 타입을 I2로 한다는 것은 인스턴스를 외부에서 제어할 수 있는 조작 장치를 인스턴스 I2의 멤버로 제한한다는 의미가 된다. 인스턴스 I2와 I3로 인해서 하나의 클래스가 다양한 형태를 띄게 되는 것이다.
'TIL > Java' 카테고리의 다른 글
[Java] toString (0) | 2022.02.01 |
---|---|
[Java] finally (0) | 2022.01.27 |
[Java] 인터페이스(interface) (0) | 2022.01.25 |
[Java] abstract (0) | 2022.01.25 |
[Java] 패키지 (0) | 2022.01.21 |