고래씌
[JAVA] 10. 다형성 본문
1. 다형성
[부모클래스 - Parent]
package com.kh.chap01_poly.part01_basic.model.vo;
public class Parent {
private int x;
private int y;
public Parent() {
}
public Parent(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return "x : " + x + ", y : " + y;
}
public void printParent() {
System.out.println("부모클래스에서 호출됨");
}
}
[자식클래스 - Child1]
package com.kh.chap01_poly.part01_basic.model.vo;
public class Child1 extends Parent{
private int z;
public Child1() {
}
public Child1(int x, int y, int z) {
super.setX(x);
super.setY(y);
this.z = z;
}
public Child1(int z) {
this.z = z;
}
public int getZ() {
return z;
}
public void setZ(int z) {
this.z = z;
}
@Override
public String toString() {
return super.toString() + ", z : " + z;
}
public void printChild1() {
System.out.println("첫번째 자식에서 호출됨");
}
}
[자식클래스 - Child2]
package com.kh.chap01_poly.part01_basic.model.vo;
public class Child2 extends Parent{
private int n;
public Child2() {
}
public Child2(int x, int y, int n) {
super(x, y);
this.n = n;
}
public Child2(int n) {
super();
this.n = n;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
@Override
public String toString() {
return super.toString() + ", n : " + n;
}
public void printChild2() {
System.out.println("두번째 자식에서 호출됨");
}
}
1) 부모타입 레퍼런스 변수로 부모타입 객체 다루기
하지만!!!!
((child1)p1).printChild1; => 접근할 수 없다!!! (강제형변환)
Parent p1 = new Parent(); 이기 때문.
Parent p1 = new Child1(); 이면 강제형변환시 접근가능하다.
2) 자식타입 레퍼런스 변수로 자식객체를 다루는 경우
Child1 c1 = new Child();
c1.printParent(); => 자동형변환이 이루어지고 있어서 부모클래스(Parent)의 printParent() 이 호출됨
▶ Child1 레퍼런스 변수로 Parent, Child1에 있는 필드 및 메소드 둘다 접근가능.
▶ Child1 레퍼런스 변수가 Parent에 있는 메소드에 접근시 자동으로 "형변환"이 진행됨.
▶ 자식에서 부모클래스로는 ★자동형변환(업캐스팅) -> 작은것에서 큰것으로 형변환된것과 같은이치
3) 부모타입, 레퍼런스 변수로 자식 객체를 다루는 경우(다형성 적용)
▶ p2.printParent() => 에러 발생하지 않음. Parent클래스 내부 메소드를 참조하기 때문
▶ p2.printChild1(); => 에러 발생. 부모에서 자식으로 자동형변환 X
▶ ((Child1)p2).printChild1(); => 부모에서 자식으로 접근하고 싶을대는 Child1 자료형으로 ★강제형변환(다운캐스팅) 후 진행!!
★ 정리
클래스 간에도 형변환 가능(단, 상속구조일 경우에만)
1. UpCasting
- 자식타입 → 부모타입으로 형변환
- 생략가능(자동형변환 개념)
ex)
- 부모 변수 = new 자식객체
2. DownCasting
- 부모타입 → 자식타입으로 형변환
- 생략불가능(강제형변환 해야함)
ex)
- ((자식)부모).자식메소드();
2. 다형성을 쓰는 이유
- 부모타입으로부터 파생된 여러가지 타입의 자식객체들을 부모클래스 하나로 다룰 수 있음
3. 다형성 장점
☞ 다형성이 적용되면 부모타입 레퍼련스 변수 "하나"로 모든 자식객체를 다 받아줄 수 있다!
☞ 하나의 부모타입으로 모든 자식객체들을 다 받을 수 있음 => 코드 수 감소, 생산성 증대, 유지보수 관리.
부모타입은 모든 형변환 가능.
☞ 자식클래스에서 자식클래스 강제형변환은 문제 발생!
① instanceof 자료형
: 현재 참조하고 있는 레퍼련스 변수(Parent)가 실제로 어떤 객체타입을 참조하고 있는지 확인할 수 있는 연산자
for(int i=0; i<arr.length; i++) {
if(arr[i] instanceof Child1) {
((Child1)arr[i]).printChild1();
}else {
((Child2)arr[i]).printChild2();
}
}
☞ arr[i]가 실제로 참조하고 있는 객체타입이 Child1이라면 true, 아니라면 false 반환
② 동적바인딩 및 정적바인딩
▶ 동적 바인딩 : 프로그램이 실행되기 전에 자동으로 컴파일되면서 정적으로는 현재 레퍼런스 변수(Parent)의 메소드를 가리키게 됨.
→ ctrl 좌클릭으로 확인
▶ 단, 참조하고 있는 자식클래스에 해당 메소드가 "오버라이딩"되어 있다면
프로그램을 시작할때는 동적으로(실제로 실행시 자식클래스의 재정의된 메소드가 실행 → ★동적바인딩
컴파일 단계에서 참조하고 있는 레퍼런스 변수의 메소드를 실행한다고 가리키는 것 → ★정적바인딩)
'JAVA > JAVA 기초' 카테고리의 다른 글
[JAVA] 10-2. 다형성 객체 배열 실습 2(Book객체) (0) | 2023.10.17 |
---|---|
[JAVA] 10-1. 다형성 실습 (0) | 2023.10.17 |
[JAVA] 상속 실습 문제 (0) | 2023.10.16 |
[JAVA] 사원 프로그램 객체 실습 (0) | 2023.10.13 |
[JAVA] 9. 상속 & 오버라이딩 (0) | 2023.10.13 |