오버라이딩과 오버로딩

kyw·2025년 9월 19일

Java

목록 보기
5/13

오버라이딩이란 무엇일까

오버라이딩(Overriding), 즉 재정의는 부모 클래스로부터 상속받은 메서드의 내용을 자식 클래스에서 자신만의 기능으로 새롭게 덮어쓰는 것을 의미한다.

부모가 물려준 기능을 그대로 사용하지 않고, 자식의 상황에 맞게 기능을 변경하거나 확장하는 객체 지향 프로그래밍의 핵심 개념 중 하나이다.


비유: 기본 설계도와 상세 설계도 blueprints
부모 클래스 (Vehicle): "달리기"라는 아주 기본적인 설계도를 가지고 있습니다. 이 설계도에는 그냥 "탈것이 달린다"라고만 간단히 적혀 있습니다.

자식 클래스 (Car): 부모의 "달리기" 설계도를 물려받았지만, 자동차는 훨씬 더 구체적인 방식으로 달립니다. 그래서 똑같은 "달리기"라는 제목의 설계도에 "엔진과 바퀴를 이용해 도로 위를 달린다"고 자신만의 상세한 내용을 새롭게 작성합니다.

여기서 자식 클래스(Car)가 부모의 기본 "달리기" 방법을 자신만의 방식으로 재정의(오버라이딩)한 것입니다.


오버라이딩의 조건

메서드를 재정의하기 위해서는 다음의 엄격한 규칙을 따라야 한다.

  • 메서드의 이름이 부모 클래스의 메서드와 완전히 동일해야 한다.
  • 메서드의 매개변수 (개수, 타입, 순서)가 완전히 동일해야 한다.
  • 메서드의 반환 타입이 동일해야 한다. (세부적으로는 부모의 반환 - 타입보다 더 구체적인 자식 타입일 수는 있다.)
  • 접근 제어자는 부모 메서드보다 더 좁은 범위로 수정할 수 없다. (예: public을 private으로 변경 불가)

코드 예시

// 부모 클래스
class Vehicle {
    void run() {
        System.out.println("탈것이 달립니다.");
    }
}

// 자식 클래스
class Car extends Vehicle {
    
    // Vehicle의 run() 메서드를 재정의(오버라이딩)
    @Override
    void run() {
        System.out.println("자동차가 도로를 달립니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.run(); // Car 클래스에서 재정의된 메서드가 호출됨
    }
}

실행 결과:
자동차가 도로를 달립니다.

myCar.run()을 호출했을 때, 부모인 Vehiclerun()이 아닌, Car 클래스에서 새롭게 정의한 run() 메서드가 실행되는 것을 볼 수 있습니다.


왜 사용해야 할까?

오버라이딩의 가장 큰 목적은 다형성(Polymorphism)을 구현하는 것이다.

다형성이란, 같은 이름의 메서드를 호출하더라도 실제 객체가 무엇이냐에 따라 각기 다른 동작을 하는 것을 의미한다.

Vehicle myVehicle = new Car(); // 부모 타입으로 선언, 자식 객체로 생성
myVehicle.run(); // 호출은 Vehicle의 run() 같지만, 실제 실행은 Car의 run()!

이처럼 오버라이딩을 통해 코드의 유연성과 재사용성을 극대화할 수 있으며, 이는 객체 지향 프로그래밍이 강력한 이유 중 하나이다. @Override 어노테이션은 바로 이러한 재정의 규칙을 잘 지켰는지 컴파일러가 확인해주는 안전장치 역할을 한다.

오버로딩이란 무엇일까?

오버로딩(Overloading)은 하나의 클래스 안에서 같은 이름의 메서드를 여러 개 정의하는 기술이다.

메서드 이름은 같지만, 매개변수의 개수나 타입을 다르게 하여 서로 다른 기능을 수행하도록 만드는 것이다.


오버로딩의 조건

오버로딩이 성립하려면 메서드 이름이 같더라도 시그니처(Signature)가 달라야 한다. 시그니처를 다르게 하는 방법은 다음과 같다.

  • 매개변수의 개수가 다르거나,
  • 개수가 같더라도 매개변수의 타입이 다르거나,
  • 타입과 개수가 같더라도 매개변수의 순서가 달라야 한다.
    주의: 반환 타입(Return Type)만 다른 것은 오버로딩으로 인정되지 않는다

코드 예시
하나의 Calculator 클래스 안에 여러 개의 add 메서드를 오버로딩한 예시다


class Calculator {

    // 1. 매개변수가 없는 경우
    int add() {
        return 0;
    }

    // 2. 정수(int) 2개를 더하는 경우
    int add(int a, int b) {
        return a + b;
    }

    // 3. 실수(double) 2개를 더하는 경우
    double add(double a, double b) {
        return a + b;
    }

    // 4. 정수 3개를 더하는 경우
    int add(int a, int b, int c) {
        return a + b + c;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator cal = new Calculator();
        
        System.out.println("결과1: " + cal.add(10, 20));       // 2번 메서드 호출
        System.out.println("결과2: " + cal.add(3.14, 2.5));   // 3번 메서드 호출
        System.out.println("결과3: " + cal.add(10, 20, 30));  // 4번 메서드 호출
    }
}

컴파일러는 cal.add(...)를 호출할 때, 전달되는 인자의 타입과 개수를 보고 어떤 add 메서드를 실행할지 정확하게 찾아낸다.

profile
作心百日

0개의 댓글