오버로딩과 오버라이딩

01_49g_63m·2024년 2월 21일
post-thumbnail

오버로딩과 오버라이딩은 객체 지향 프로그래밍에서 다형성을 구현하는 두가지 개념이다.
사실 두 개의 개념은 전혀 다른 의미를 가지고 있지만, 이름이 비슷해서 헷갈리기 쉽다.

  • 오버로딩(overloading)
    : 같은 메서드 이름을 가지면서 매개변수의 타입, 개수, 또는 순서가 다른 여러 메서드를 정의하는 것을 말한다.

  • 오버라이딩(overriding)
    : 부모 클래스에서 이미 정의된 메서드를 자식 클래스에서 같은 메서드 이름, 매개변수 타입, 반환 타입으로 다시 정의하는 것을 말한다.

글자로만 보면 사실 확 머리에 들어오지 않기 때문에
코드로 예시를 들어 설명하자면!

오버로딩

  • 아래는 오버로딩을 적용하지 않은 코드다.
public class WithoutOverloadingCode {

    // 정수형 매개변수를 받는 메서드
    public int addIntegers(int a, int b) {
        return a + b;
    }

    // 실수형 매개변수를 받는 메서드
    public double addDoubles(double a, double b) {
        return a + b;
    }

    // 세 개의 정수형 매개변수를 받는 메서드
    public int addThreeIntegers(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        WithoutOverloadingExample example = new WithoutOverloadingExample();
        
        System.out.println(example.addIntegers(1, 2));           // 3
        System.out.println(example.addDoubles(1.5, 2.5));        // 4.0
        System.out.println(example.addThreeIntegers(1, 2, 3));   // 6
    }
}

위에 코드는 addIntegers, addDoubles 처럼 각각의 메서드에 대해 별도의 이름을 정의하면서, 이름 충돌 및 가독성이 감소하면서 코드 중복이 될
가능성이 크다.

  • 아래는 오버로딩을 적용한 코드다.
public class OverloadingCode {

    // 정수형 매개변수를 받는 메서드
    public int add(int a, int b) {
        return a + b;
    }

    // 실수형 매개변수를 받는 메서드 (매개변수 타입이 다름)
    public double add(double a, double b) {
        return a + b;
    }

    // 세 개의 정수형 매개변수를 받는 메서드 (매개변수 개수가 다름)
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        OverloadingExample example = new OverloadingExample();
        
        System.out.println(example.add(1, 2));          // 3
        System.out.println(example.add(1.5, 2.5));      // 4.0
        System.out.println(example.add(1, 2, 3));       // 6
    }
}

오버로딩을 적용하면, add() 메서드로 통일하여 같은 메서드 이름을 가지면서 매개변수의 타입 및 개수에 따라 다르게 동작하는 것을 확인 가능하다.

오버라이딩

  • 아래는 오버라이딩을 적용한 코드입니다.
class Animal {
    public void makeSound() {
        System.out.println("동물이 소리를 낸다.");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("개가 짖는다.");
    }
}

public class OverridingExample {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 업캐스팅

        animal.makeSound(); // 실제로 실행되는 메서드는 Dog 클래스의 makeSound() 메서드
    }
}

위 코드에서 'Dog'클래스는 'Animal'클래스의 'makeSound' 메서드를 오버라이딩한다. 부모 클래스의 메서드가 자식 클래스에서 재정의되어 실행된다.

  • 출력값
개가 짖는다.

상속을 통해 받았다고 해도 자식이 이를 다시 정의했기 때문에,
자식이 정의한 메소드의 결과값이 출력된다.

하지만 오버로딩과 오버라이딩을 사용할 시 조건이 있다.

오버로딩 조건

❗한 클래스 내에서 메소드 명이 동일해야 한다.
❗매개변수의 개수 또는 타입이 달라야 한다.
❗매개변수는 같고 리턴타입이 다른 경우는 성립 불가능

오버라이딩 조건

❗부모 클래스의 메소드와 메소드 이름이 동일해야 한다.
❗매개변수의 타입, 개수, 순서가 일치해야 한다.
❗리턴 타입이 동일해야 한다.
❗접근 제한자는 부모 클래스의 메소드와 같거나 더 넓은 범위여야 한다.
❗부모 메소드의 예외와 같거나 예외의 개수를 줄일 수 있다.

그럼 아래는 오버로딩일까 오버라이딩일까?

public class EX03 {
    public static void main(String[] args) {
        Child child = new Child();
        child.method();
    }
}

class Parent {
    public void method() {
        System.out.println("P");
    }
}

class Child extends Parent{
    public void method(String alphabet) {
        System.out.println("C");
    }
}

부모의 메소드도 들고 있고, 자신의 메소드도 들고 있기 때문에
오버로딩이다.

참고

https://s-bug.tistory.com/90

profile
CODING, AND MANY MORE

0개의 댓글