
오버로딩과 오버라이딩은 객체 지향 프로그래밍에서 다형성을 구현하는 두가지 개념이다.
사실 두 개의 개념은 전혀 다른 의미를 가지고 있지만, 이름이 비슷해서 헷갈리기 쉽다.
오버로딩(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");
}
}
부모의 메소드도 들고 있고, 자신의 메소드도 들고 있기 때문에
오버로딩이다.