Language/Java

[Java] 오버라이딩과 오버로딩, 그리고 업캐스팅

xagyeongxx 2025. 10. 25. 23:38

1. 오버라이딩(overriding)과 오버로딩 (overloading)

class ClassA {
    ClassA() {                 // 생성자
        System.out.print('A');
        this.prn();
    }
    void prn() {
        System.out.print('B');
    }
}

class ClassB extends ClassA {
    ClassB() {
        super();
        System.out.print('D');
    }
    void prn() {              // 오버라이딩
        System.out.print('E');
    }
    void prn(int x) {         // 오버로딩
        System.out.print(x);
    }
}

오버라이딩

  • 상속 관계에서, 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것.
  • class ClassA { void prn() { System.out.print('B'); } } class ClassB extends ClassA { void prn() { System.out.print('E'); } // 오버라이딩 }
  • 이와 같이 상속으로 인해 동일한 이름의 메소드가 여러 개인 경우,자식 클래스의 prn() 메소드만 사용된다. (=ClassB의 prn())
  • ⇒ 이를 메소드 오버라이딩 (혹은 메소드 재정의) 라고 한다.
  • 부모 클래스에서 정의된 prn() 메소드는 자식 클래스의 prn() 메소드에 의해 재정의 되어,
  • 특징은 메서드 이름, 매개변수, 반환형이 모두 동일해야 한다.
📌 “절대” 부모 버전이 호출되지 않는다. (super. 제외!)
  • 재밌는 건, 오버라이딩(overriding)된 메서드는 부모 타입으로 업캐스팅 되더라도,
  • 오버로딩
    • 같은 이름의 메서드를 여러 개 정의하되, 매개변수의 타입이나 개수를 다르게 하는 것.prn() : 매개변수가 없음즉, 같은 이름(prn)이지만 매개변수 리스트가 다르므로 오버로딩이다.
    • prn(int x) : 매개변수로 정수를 받음
    • void prn() { System.out.print('E'); } void prn(int x) { System.out.print(x); }

2. 타입 형변환 (업캐스팅)

업캐스팅, 다운캐스팅이 있지만, 업캐스팅에 대해 다뤄보겠다.

  • 업캐스팅
class Parent {
    int value = 1;
    Parent() {
        System.out.println("1. Parent 생성자 실행 시작");
        this.print();
        // 🔥 오버라이딩된 메서드 호출 지점   -> Child의 print()가 호출됨
        System.out.println("2. Parent 생성자 실행 종료");
    }

    void print() {
        System.out.println("Parent print()");
    }
}

class Child extends Parent {
    int value = 10;

    Child() {     
        // 항상 super(); 이 기본 실행됨. 즉 Parent() -> Child() 실행
        System.out.println("3. Child 생성자 실행");
        print();
        System.out.println("4. Child 생성자 종료");
    }

    @Override
    void print() {
        System.out.println("Child print(), value = " + value);
    }
}

public class Main {
    public static void main(String[] args) {
        Parent p = new Child();   // 업캐스팅
    }
}

 

결과는 이렇게 될것이다.

1. Parent 생성자 실행 시작

Child print(), value = 0

→ 아직 Child의 생성자 본문이 실행X, Child의 value는 아직 기본값 0으로 남아 있음

2. Parent 생성자 실행 종료

3. Child 생성자 실행

Child print(), value = 10

4. Child 생성자 종료

 

⇒ 뭘해도, 업캐스팅을 했을 지언정 다형성으로 인해서 Parent의 print는 무시됨!!!!!!!!!!!!