[자바JAVA]클래스 : 다형성(Polymorphism)
캐스팅은 OOP(객체지향프로그래밍) 에서 매우 중요하다.
왜냐하면 캐스팅은 OOP의 다형성과 관련이 있기 때문이다.
다형성
java에서 기본형이 아닌 참조형데이터일때, 그리고 상속관계에 있을 때에 한정해서 슈퍼클래스 타입으로 서브클래스 객체를 레퍼런스할 수 있는 성질.
- 동일한 형태의 구성으로 다양한 결과를 사용하는 것
- 인터페이스에서 다형성 사용하는 이유 :
- 하위클래스들 작성시 동일한 구조를 강요하기위해서(=통일성) 사용하기 위해서
- request,response 정보를 사용하기 위해서
캐스팅종류(casting, 형변환)
캐스팅은 크게 자동 형변환, 명시적 형변환으로 나뉜다.
또 데이터 타입에 따라 다르다.
| 데이터타입 | 캐스팅종류 |
|---|---|
| 기본형 | 자동 형변환 |
| 기본형 | 명시적 형변환 |
| (상속관계의) 참조형 | 자동 형변환(UpCasing) |
| (상속관계의) 참조형 | 명시적 형변환(DownCasing) |
상속관계일때 캐스팅은 크게 두가지로 나뉜다.
두 캐스팅의 전제조건은 상속이다.
UpCasting(업캐스팅 = 자동형변환) : 서브클래스가 슈퍼클래스로 형변환 되는 것.
- 슈퍼클래스의 레퍼런스에 서브클래스의 인스턴스(객체)를 저장.
- 컴파일러가 자동으로 형변환
- 업캐스팅을 하면 상속 받은 멤버(멤머변수,메서드)만 쓸 수 있다.
- 업캐스팅을 참조영역이 감소했다고 표현한다 WHY? 원래 Child는 Parent와 Child을 둘 다 쓸 수 있었는데 업캐스팅때문에 상속받은 것만 쓸 수 있게 됨
- 업캐스팅하는 3가지방법
1 | Parent p = new Parent(); |
DownCasting(다운캐스팅 = 명시적 형변환) : 슈퍼클래스가 서브클래스로 형변환 되는 것.
- 다운캐스팅은 컴파일러가 자동으로 형변환 X => WHY? 해당객체가 존재하지 않을 수도 있기때문에
- 따라서 개발자가 직접 타입을 구현해야한다. => 예외가 발생한다고 표현함.
- UpCasting이 일어난 값에 한해서만 DownCasting이 가능하다.
- 서브클래스의 레퍼런스에 슈퍼클래스의 인스턴스(객체)를 저장.
1 | Parent p = new Parent(); |
다형성이 왜 필요할까?
- 다형성과 참조형 객체의 형변환
- insteadof 연산자
- 참조변수의 레벨에 따른 객체멤버 연결
- 공변 리턴 타입
다형성과 참조형 객체의 형변환
자바의 데이터타입은 크게 두가지로 나뉜다.
- 기본형데이터(8가지) : 기본 데이터형에서의 캐스팅은 원칙적으로 데이터손실을 막고자 한다.
- 종류 : 자동 형변환, 명시적 형변환.
아래는 double형을 int형으로 형변환한 코드이다.
- 종류 : 자동 형변환, 명시적 형변환.
1 | int a = (int)1.0; |
- 참조형데이터
- 종류 : 자동 형변환, 명시적 형변환.
- 조건 : 상속관계일때 성립.
아래 예시를 보자.
슈퍼클래스인 Parent와 서브클래스 Child가 있다.
서브클래스 Child의 데이터양은 슈퍼클래스인 Parent보다 항상 많다.
서브클래스가 슈퍼클래스를 포함하기때문이다.
기본적으로 같은 타입을 한 배열에 넣을 수 있다.
1 | Person[] p = {new Person, new Person}; |
하지만 spiderMan과 AquaMan은 person에 포함된다고 볼 수 있다.
- 타입이 다른 참조형데이터를 하나의 배열에 넣을 순 없을까?
할 수 있다!
다형성을 적용하여 형변환을 하면 된다.
상속관계인 경우에만 타입이 다른 참조형데이터를 하나의 배열에 묶을 수 있다.
1 | //배열선언 2가지 방법 : 1번과2번은 동일한 값을 가진다 |
instanceof 연산자
슈퍼타입을 언제나 형변환 연산자를 통해 서브타입으로 변경할 수는 없다.
먼저 메모리에 있는 객체가 형변환을 위한 충분조건을 갖추고 있는지 확인해봐야한다.
이때 사용할 수 있는 연산자가 instansof이다.
- 실제 메모리에 있는 특정 클래스 타입인지를 boolean타입으로 리턴한다.
따라서 결과가 true일때 형변환 처리하면 된다.
1 | class Person {} |
참조변수의 레벨에 따른 객체멤버 연결
상속을 이용하면 조상의 멤버들을 그대로 물려받으며 필요할 때 자손은 그 멤버들을 재정의할 수 있다.
아래 코드를 보고 답변해보자
- SubClass의 멤버변수는 몇개인가?
- SubClass의 메서드는 몇개인가?
- main메서드 실행 값은 순서대로 어떻게 될 것인가?
1 | class SuperClass{ |
- SubClass의 멤버변수는 2개
- SubClass의 메서드는 오버라이딩되었기때문에 메서드는 1개다. 애노테이션(Annotation)이 있으면 구분이 쉬우니 꼭 적자. => 애노테이션위치는 subClass의 멤버변수와 메서드 사이에 위치!
- 다이나믹바인딩때문에 super클래스의 메서드가 아니라 sub클래스의 메서드이다. 그래서 sub에서 재정의된 메서드가 실행된다.
공변 리턴 타입
원래 메서드 오버라이딩시 서브메서드의 리턴 타입은 슈퍼클래스의 리턴 타입과 같아야 한다.
하지만 공변 리턴타입는 슈퍼클래스의 리턴 타입을 서브 클래스 범위 안에서 다양하게 사용할 수 있다.
리턴타입이 변화되기때문에 오버라이딩 규칙에 위배되지만 JDK 1.5버전부터는 예외로 허용하고있다.
- 주의점 : 상속관계상의 서브클래스에서만 가능.
- 장점 : 형변환의 번거로움을 많이 줄일 수 있다.
![[OS/WINDOW]배포후 서버재시작에 batch와 윈도우 스케줄러 활용하기](https://cdn.pixabay.com/photo/2012/03/04/00/50/board-22098_960_720.jpg)
![[블로그]헥소테마에서 댓글기능 facebook에서 utterances로 변경하기](https://miro.medium.com/max/1600/1*aOv6h3h_v9PQWa03zGACnw.png)