다형성은 무엇이며, 어떻게 사용할까?
다형성 (Polymorphism)
--
다형성은
하나의 객체가 여러 가지 형태를 가질 수 있는 성질을 의미한다.
즉, 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 하는 것이다.
부모클래스 타입의 참조변수로 자식클래스의 인스턴스를 참조하는 것이다.
부모클래스명 객체명 = new 자식클래스생성자();
class Parent { ... }
class Child extends Parent { ... }
Parent op = new Child(); // 부모타입의 참조변수로 자식 인스턴스를 참조
다형성을 이용하면
해당 객체의 구성은 부모타입(부모클래스)으로 이루어져 있으며
내용(데이터)은 자식 객체를 참조하는 것으로
간단하게 구성은 부모 클래스고, 데이터는 자식 클래스의 내용을 참조하여 사용하는 객체다.
위 그림처럼
op 객체의 구조는 Parent 클래스와 동일하며
해당 구조의 내용은 Child 클래스의 내용을 참조하여 사용한다.
자식클래스에서 "A"멤버 변수처럼 부모클래스와 동일한 이름의 변수를 추가한 것은
메서드의 오버라이딩처럼 재정의를 한 것이 아니라
부모 클래스의 "A" 변수와 자식 클래스의 "A" 변수는 전혀 다른 변수다.
[ 자식 클래스는 부모 클래스의 내용을 재정의(오버라이딩)는 가능하지만, 재선언(기존 값 변경)은 불가능 ]
주의
자식 타입의 참조변수로 부모타입의 인스턴스를 참조하는 것은 불가능하다.
[ Child op = new Parent(); ]
이유
참조하려는 Parent의 멤버 개수보다 참조변수 op의 멤버 개수가 더 많기 때문에
참조변수인 op에서 사용해야할 멤버들 중에서
참조하려는 Parent 인스턴스에 존재하지 않은 멤버가 있기 때문에 사용할 수 없게 된다.
--
참조변수의 형변환
--
기본형 변수처럼 참조변수도 형변환이 가능하다.
규칙
- 서로 상속 관계에 있는 클래스 사이에서만 형변환이 가능하다.
- 자식타입에서 부모타입으로 형변환은 생략 가능
(기본형 변수에서도 작은 자료형에서 큰 자료형으로 형변환 생략 가능한 것과 동일한 이유)
참조변수 형변환 기본 형식
(클래스명)객체명
class AAA { ... }
class BBB extends AAA { ... }
class CCC extends BBB { ... }
class DDD extends AAA { ... }
AAA a = null;
BBB b = new BBB();
CCC c = null;
DDD d = new DDD();
a = b; // 자식타입에서 부모타입으로 형변환은 생략 가능
c = (CCC)a; // 부모타입에서 자식타입으로 형변환은 생략 불가
c = (CCC)d; // 에러!! 서로 상속관계가 아님
d = (DDD)c; // 에러!! 서로 상속관계가 아님
instanceof 연산자를 이용하면
형변환 가능한 클래스인지 확인할 수 있다.
(true면 상속 관계이므로 형변환 가능)
--
매개변수의 다형성
--
매개변수에도 다형성을 적용할 수 있다.
class AAA { ... }
class BBB extends AAA { ... }
class CCC extends AAA { ... }
class DDD extends AAA { ... }
void test(BBB b) { ... }
void test(CCC c) { ... }
void test(DDD d) { ... }
원래 매개변수에 참조변수를 받으려면 따로 매개변수만 변경하여 생성해야 한다.
이러한 경우 자식 클래스가 많아질수록 해당 메서드를 계속 추가하여 구현해야 하는 번거로움이 존재한다.
다형성을 적용하면 아래 코드처럼 하나의 메서드로 간단히 처리할 수 있다.
void test(AAA a) { ... }
최상위 부모 클래스를 매개변수로 지정하면 해당 클래스의 자식 타입은 모두 사용할 수 있게 된다.
매개변수에 다형성을 사용할 수 있는 이유는
매개변수에 인자를 넣게 되면
[ 매개변수타입 매개변수명 = new 인자타입(); ]
형태로 객체를 생성하게 되기 때문이다.
--
'Language > Java' 카테고리의 다른 글
내부 클래스 (+ 익명 클래스) (0) | 2024.10.23 |
---|---|
인터페이스 (1) | 2024.10.22 |
제어자, 접근 제어자 (+ static, final, abstract, 추상 클래스, 추상 메서드) (0) | 2024.10.20 |
package와 import (+ static import) (1) | 2024.10.19 |
[클래스] 변수와 메서드 (+ 초기화 블록) (0) | 2024.10.18 |