오버로딩(Overloading)과 오버라이딩(Overriding) 차이에 대해서 알아보자
들어가며
오버로딩과 오버라이딩은 자바에서 매우 중요한 개념입니다. 이 두 개념은 OOP의 특징은 다향성을(Polymorphism)
을 구현하는데 매우 중요하게 사용됩니다. 그렇기때문에 이 두 개의 개념의 대해서 차이를 알아보도록 하겠습니다.
오버로딩(Overloading)
한 클래스 내에서 같은 메소드를 사용하는데 매개변수만 다를 때를 오버로딩을 사용해 매개변수 값만 다르게 해서 같은 이름의 메서드를 사용할 수 있다. 즉, 오버로딩은 같은 이름의 메소드를 여러 개로 정의하는 것을 말합니다.
사용 조건
모든 메소드에 오버로딩을 적용할 수 있는 것은 아니다. 다음과 같은 두 가지 조건을 만족시켜야 한다.
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
만약 두 가지 조건을 충족시키지 않고 실행한다면 컴파일 오류가 발생하는 것을 볼 수 있다. 또 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
사용 예시
우리는 이미 오버로딩된 메서드를 사용한 적이 있습니다. 자바를 처음 시작할 때 우리는 "Hello World"를 출력하기 위해 System.out.println("Hello World")을 사용해 보았을 것입니다. 이때 사용되는 println() 메서드는 오버로딩된 메서드입니다.
API 문서를 통해 println 메서드를 살펴보면 다음과 같은 메소드들이 작성되어 있는 것을 볼 수 있습니다. 이러한 메소드들은 모두 println이라는 이름을 가지고 있지만, 파라미터로 받는 타입만 다를 뿐입니다. 이렇게 오버로딩을 통해 같은 클래스 내에서 중복된 메소드를 여러 개 정의하여 사용할 수 있습니다.
public void println() { newLine(); }
public void println(boolean x) { synchronized (this) { print(x); newLine(); } }
public void println(char x) { synchronized (this) { print(x); newLine(); } }
public void println(int x) { synchronized (this) { print(x); newLine(); } }
public void println(long x) { synchronized (this) { print(x); newLine(); } }
public void println(float x) { synchronized (this) { print(x); newLine(); } }
public void println(double x) { synchronized (this) { print(x); newLine(); } }
public void println(char x[]) { synchronized (this) { print(x); newLine(); } }
public void println(String x) { synchronized (this) { print(x); newLine(); } }
public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); } }
이렇게 오버로딩을 이용하면 같은 이름의 메소드를 다양한 방식으로 사용할 수 있습니다.
사용 장점
만약 클래스 내에 값 더하기 메서드인 add()가 있다고 가정해 봅시다. 오버로딩을 사용하지 않는다면 처음에는 int 타입만을 사용하여 더하는 메소드를 만들었을 것입니다. 그런데 나중에 double 타입을 사용하는 더하기 메소드를 추가하려면, 메소드 이름을 doubleAdd와 같이 변경하거나 중복되지 않는 다른 이름을 사용해야 할 것입니다. 이렇게 하면 메소드 이름을 보고도 해당 메소드가 어떤 타입을 사용하는지 명확히 이해하기 어려울 뿐만 아니라 코드의 가독성도 떨어지게 됩니다.
그러나 오버로딩을 사용한다면, add() 메소드 하나로 여러 타입을 사용하여 값을 더할 수 있습니다. 이렇게 함으로써 코드의 가독성이 향상되며, 메소드 이름만으로도 어떤 타입을 사용하는지 명확히 이해할 수 있습니다. 따라서 오버로딩을 사용하면 코드가 간결하고 이해하기 쉬워지며, 중복된 코드를 피할 수 있습니다
오버라이딩(Overriding)
오버라이딩은 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 합니다.
사용 조건
오버라이딩을 사용하기 위해서는 다음과 조건을 만족해야 컴파일 오류 없이 사용가능하다.
자손클래스에서 오버라이딩하는 메서드는 조상클래스의 메서드와 다음 조건을 만족해야 한다.
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.
조상클래스의 메서드를 자손 클래스에서 오버라이딩할 때 다음 조건을 만족해야 한다.
- 접근 제어자를 조상 클래스 메서드보다 좁은 메서드로 변경할 수 없다(조상클래스 protected, 자식클래스 protected, public만 사용가능)
- 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
- 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없다.
사용 예시
오버라이딩 예시
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
animal.sound();
Animal dog = new Dog();
dog.sound();
Animal dat = new Cat();
dat.sound();
}
public static class Animal{
public void sound(){
System.out.println("동물 소리");
}
}
public static class Dog extends Animal{
@Override
public void sound() {
System.out.println("강이지는 왈왈~~");
}
}
public static class Cat extends Animal{
@Override
public void sound() {
System.out.println("고양이는 야옹야옹~~");
}
}
}
위와 같이 동물 Aniaml클래스의 "동물 소리"를출력하는 sound() 메서드가 있다. 이제 고양이와 야옹이는 각각 다른 울음소리를 내는데 오버라이딩을 통해서 맞는 울음소리를 출력하도록 오버라이딩을 했다. 이제 각 Animal,Dog,Cat의 인스턴스를 생성해서 sound() 메서드를 실행하면 각각 의 맞는 println이 출력되는것을 볼수있다. 이렇게 오버라이등을 조건에 맞춰 사용하면 된다.
오버라이딩 장점
오버라이딩은 다형성을 통해 동일한 메소드 이름을 사용하면서도 각 클래스에서 다른 동작을 구현할 수 있어 유연성을 높입니다. 또한, 자식 클래스에서 부모 클래스의 메소드를 재정의하여 기능을 확장하거나 변경할 수 있어 기능의 확장성을 제공하며, 코드의 가독성과 유지 보수성을 향상합니다.
정리
- 오버로딩(overloading) : 기존에 중복되거나 없는 메서드를 재정의한다.
- 오버라이딩(overriding) : 조상으로부터 받은 메소드를 상속받아 메서드의 내용을 원하는 내용으로 변경해 사용하는 것
public class Question {
void test() {};
}
class Answer extends Question {
void test() {
System.out.println("오버로딩? 오버라이딩?");
}
void test1(int a) {
System.out.println("오버로딩? 오버라이딩?" + a);
}
void test1(int a) {
System.out.println("오버로딩? 오버라이딩?" + a);
}
void test2(int a) {
System.out.println("오버로딩? 오버라이딩?" + a);
}
}
위에 코드를 보고 어떤 것이 오버로딩인지 오버라이딩인지 알아야 하며 오류가 발생하는지 파악할 수 있어야 한다. 답을 아신다면 댓글에 남겨주시면 감사하겠습니다.!
'Java' 카테고리의 다른 글
[JAVA] 자바의 JVM, JDK, JRE: 자바 개발 환경의 핵심 개념 (0) | 2024.02.23 |
---|