BACK/JAVA

[JAVA] 실전 자바 - 다형성(다형적 참조, 메서드 오버라이딩)

연듀 2024. 1. 30. 17:09

 

 

다형성

한 객체가 여러 타입의 객체로 취급될 수 있는 능력

 

 

[다형성의 핵심 이론]

  1. 다형적 참조: 하나의 변수 타입으로 다양한 자식 인스턴스를 참조할 수 있는 기능
  2. 메서드 오버라이딩: 기존 기능을 하위 타입에서 새로운 기능으로 재정의

 

 

다형적 참조

 

부모 타입의 변수가 자식 인스턴스 참조 가능

 

Parent poly = new Child();

 

 

자식 타입인 Child를 생성했기 때문에 메모리 상에 Child, Parent 모두 생성

 

💡 부모는 자식을 담을 수 있다.

 

 

 

상속 관계는 부모 방향으로 찾아 올라갈 수 있지만 반대는 불가능하다.

poly 는 Parent 타입이므로 childMethod() 를 찾을 수 없어 컴파일 오류 → 캐스팅이 필요

 

 

 

다형성과 캐스팅

 

다운캐스팅

Parent poly = new Child();
Child child = (Child)poly; // 다운캐스팅(부모 타입 -> 자식 타입) 
child.childMethod(); 

// = ((Child)poly).childMethod(); 일시적 다운 캐스팅 

 

 

주의: poly의 타입은 그대로 Parent로 유지된다.

poly의 참조값을 꺼내고 꺼낸 참조값이 Child 타입이 되는 것이다.

 

다운 캐스팅 주의점

Parent parent1 = new Child();
Child child1 = (Child)parent1;
child1.childMethod(); // 문제 없음

 

Child()로 생성이 되어 있기 때문에 childMethod() 호출이 가능

 

Parent parent2 = new Parent();
// Child child2 = Parent2() 컴파일 오류 
Child child2 = (Child)parent2; // 런타임 오류 - ClassCastException
child2.childMethod(); // 실행 불가

 

 

Parent로 생성이 되어 있어 메모리 상에 Child 가 존재하지 않아 Child의 메소드 사용 불가 → 예외

 

업캐스팅

Child child = new Child();
Parent parent1 = (Parent)child; // 업캐스팅 생략 권장
parent1.parentMethod(); 

 

💡 객체를 생성하면 해당 타입의 상위 부모 타입은 모두 함께 생성되기 때문에 위로만 타입을 변경하는 업캐스팅은 항상 안전하다.

     → 캐스팅 생략 가능

 

💡다운캐스팅은 인스턴스에 존재하지 않는 하위 타입으로 캐스팅하는 문제가 발생할 수 있어 위험하다.

     → 명시적으로 캐스팅 해줘야 함

 

 

 

자식 C의 객체를 생성하면 인스턴스 내부에 부모가 모두 생성된다.

 

 

 

B 인스턴스에 C는 생성되지 않아 B → C 다운 캐스팅은 런타임 오류 발생한다. 

 

 

instanceof

참조하는 인스턴스 확인

public class CastingMain5 {
	public static void main(String[] args) {
		Parent parent1 = new Parent(); 
		System.out.println("parent1 호출"); 
		call(parent1);
		Parent parent2 = new Child(); 
		System.out.println("parent2 호출"); call(parent2);
	}
	

	private static void call(Parent parent) {
		parent.parentMethod();
		if (parent instanceof Child) {
		System.out.println("Child 인스턴스 맞음"); 
		Child child = (Child) parent;
		child.childMethod();
		} 
	}
}

/*
parent1 호출
Parent.parentMethod
parent2 호출
Parent.parentMethod
Child 인스턴스 맞음
Child.childMethod
*/

 

 

 

다형성과 메서드 오버라이딩

 

 

멤버 변수는 오버라이딩 안되고, 메서드는 오버라이딩 된다.

 

 

Child child = new Child();

 

Parent parent = new Parent();

Parent poly = new Child();

오버라이딩 된 메서드는 항상 우선권을 가진다.

오버라이딩 된 Child.method() 가 실행된다.