다형성
다형성은 상속과 함께 객체지향개념의 중요한 특징 중의 하나이다!
상속과 깊은 관계가 있으므로 아래 글에서 상속 부분을 봐주시면 감사하겠다 ㅎㅎ...
[JAVA] 객체지향 클래스(OOP) 총 정리(2)
상속(inheritance) 상속이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다. 예시를 보며 이해해보자 class Parent { // } class Child extends Parent{ // } 위의 소스에서 Parent클래스는 부모클
y-it.tistory.com
다형성(polymorphism)이란 하나의 객체가 여러 가티 타입을 가질 수 있는 것을 의미한다.
자바에선 대표적으로 오버로딩, 오버라이딩, 업캐스팅, 다운캐스팅, 인터페이스, 추상메서드, 추상클래스 방법이 모두 다형성에 속한다고 보면 된다.
참조 변수의 다형성
자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있다.
이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있다!
class Parent { ... }
class Child extends Parent { ... }
...
Parent pa = new Parent(); // 허용
Child ch = new Child(); // 허용
Parent pc = new Child(); // 허용
Child cp = new Parent(); // 오류 발생.
특정 타입의 참조 변수로는 당연히 같은 타입의 인스턴스를 참조할 수 없다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수와 같기 때문이다.
또한 부모 클래스 타입의 참조 변수로도 자식 클래스 타입의 인스턴스를 참조할 수 있다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문이다.
하지만 반대의 경우인 자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스를 참조할 수 없다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문이다.
클래스는 상속을 통해 확장될 수는 있어도 축소될 수는 없으므로, 자식 클래스에서 사용할 수 있는 멤버의 개수가 언제나 부모 클래스와 같거나 많게 된다!
참조 변수의 타입 변환
참조 변수도 다음과 같은 조건에 따라 타입 변환을 할 수 있다.
1. 서로 상속 관계에 있는 클래스 사이에만 타입 변환을 할 수 있다.
2. 자식 클래스 타입에서 부모 클래스 타입으로의 타입 변환은 생략할 수 있다.
3. 하지만 부모 클래스 타입에서 자식 클래스 타입으로의 타입 변환은 반드시 명시해야 한다.
참조 변수의 타입 변환도 기본 타입 변환과 마찬가지로 타입 캐스트 연산자(())를 사용한다.
// (변환할타입의클래스이름) 변환할참조변수
class Parent { ... }
class Child extends Parent { ... }
class Brother extends Parent { ... }
...
Parent pa01 = null;
Child ch = new Child();
Parent pa02 = new Parent();
Brother br = null;
pa01 = ch; // pa01 = (Parent)ch; 와 같으며, 타입 변환을 생략할 수 있음.
br = (Brother)pa02; // 타입 변환을 생략할 수 없음.
br = (Brother)ch; // 직접적인 상속 관계가 아니므로, 오류 발생.
instanceof 연산자
이러한 다형성으로 인해 런타임에 참조 변수가 실제로 참조하고 있는 인스턴스의 타입을 확인할 필요성이 생긴다. 실제로 괜찮겠거니 생각하고 교육서버에 배포했는데, 런타임에서 에러를 뿜은 적이 있다......
자바에서는 instanceof 연산자를 제공하여, 참조 변수가 참조하고 있는 인스턴스의 실제 타입을 확인할 수 있도록 해준다.
참조변수 instanceof 클래스이름
왼쪽에 전달된 참조 변수가 실제로 참조하고 있는 인스턴스의 타입이
오른쪽에 전달된 클래스 타입이면 true 반환, 아니면 false 반환
class Parent { }
class Child extends Parent { }
class Brother extends Parent { }
public class Polymorphism01 {
public static void main(String[] args) {
Parent p = new Parent();
System.out.println(p instanceof Object); // true 출력
System.out.println(p instanceof Parent); // true 출력
System.out.println(p instanceof Child); // false 출력
System.out.println();
Parent c = new Child();
System.out.println(c instanceof Object); // true 출력
System.out.println(c instanceof Parent); // true 출력
System.out.println(c instanceof Child); // true 출력
}
}
'개발 > JAVA' 카테고리의 다른 글
[JAVA] 인터페이스(Interface) 총 정리 (0) | 2023.03.01 |
---|---|
[JAVA] 추상클래스(Abstract Class) 총 정리 (0) | 2023.02.27 |
[JAVA] 객체지향 클래스(OOP) 총 정리(2) (1) | 2023.02.26 |
[JAVA] 객체지향 클래스(OOP) 총 정리(1) (0) | 2023.02.25 |
[JAVA] 배열(Array) 총 정리 (0) | 2023.02.22 |