요약
자바를 통해 프로그래밍을 해보신적이 있다면 Overloading과 OverRiding에 대해 접해 보셨을겁니다. 하지만 누군가가 Overloading이랑 OverRiding의 차이에 대해 물어본다면 무엇인지는 알지만 잘 정리된 말로 대답하기 쉽지 않습니다.
오버로딩과 오버라이딩은 메서드를 재정의하는 방법이지만, 목적과 사용 방법에 차이가 있습니다.
오버로딩은 같은 이름의 메서드를 여러 개 정의하되, 매개변수의 개수나 타입이 다르게 하는 것입니다.
이를 통해 같은 기능을 수행하되 다양한 매개변수를 받을 수 있는 메서드를 구현할 수 있습니다.
반면에 오버라이딩은 상속 관계에서 자식 클래스가 부모 클래스의 메서드를 재정의하는 것입니다.
메서드의 시그니처는 동일하게 유지되지만, 구현 내용이 변경되어 자식 클래스의 요구에 맞게 동작할 수 있습니다.
이를 통해 다형성을 구현할 수 있습니다.
이렇게 답변하실 수 있는 분은 이 글을 읽지 않으셔도 됩니다!
다형성
다형성이란 하나의 메서드나 클래스가 있을 때 그것이 다양한 방법으로 동작하는 것을 말하며, 자바에서는 주로 오버로딩과 오버라이딩을 통해서 다형성을 지원합니다.이 둘에 대한 개념을 처음 접하게 되면 헷갈릴 수 있는데 이 글을 읽는 여러분은 딱 한가지를 명심하셨으면 좋겠습니다
- 오버로딩(
확장의 개념
) : 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 사용하는 것 - 오버라이딩(
재정의 개념
) : 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것
오버로딩(Overloading)
오버로딩이란 같은 이름의 메서드를 여러개 정의하고, 매개변수의 유형과 개수를 다르게 하여 다양한 유형의 호출에 응답할 수 있도록 하는 방식입니다.
이러한 개념에 대해 처음 접해보시는 분은 이게 무슨말이야?? 라고 하실수 있으니 예제 코드와 함께 이해해보도록 하겠습니다!
public class OverLoadingTest {
@Test
void test(){
System.out.println(3);
System.out.println("3");
System.out.println('3');
}
}
우리가 익숙하게 사용하는 println() 메서드에는 이러한 오버로딩이 잘 반영되어있습니다.
위 코드의 경우 int타입
인 3, String 타입
인 "3", char 타입
인 '3' 모두다 정상적으로 출력이 됩니다.
-> 예를들어 println(int x){ 내부 로직 }; 와 같이 println 메서드가 정의되어있다면 String 타입의 "3"을 넣었을때는 오류가 나야겠죠?
이를 이해하기 위해 println() 내부 코드를 살펴보겠습니다!
public void println(int x) {
synchronized (this) {
print(x);
newLine();
}
}
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
public void println(char x) {
synchronized (this) {
print(x);
newLine();
}
}
위와 같이 println()이라는 메서드는 오버로딩
되어있기 때문에 위의 테스트 코드는 정상적으로 동작하는 것입니다 ^^
다시 한번 핵심을 짚어 드리자면 메서드 이름은 같지만 매개변수의 개수나 타입을 다르게 하여, 다양한 유형의 호출에 응답할 수 있도록 하는 것
이 오버로딩입니다.
오버라이딩
오버라이딩은 상위 클래스로부터 상속받은 메서드의 동작만을 재정의하는 것입니다.
overriding을 한다면 상위 클래스가 가지고 있는 멤버 변수와 메서드를 하위 클래스에서 그냥 사용하거나, 재정의
해서 사용할 수 있습니다.
이 또한 처음 접하면 모호하실수 있으니 코드로 살펴보겠습니다!
class Mother{
int heritage = 1000;
int getHeritage(){
return this.heritage;
}
}
class Son extends Mother{
}
@Test
void test(){
Son son = new Son();
System.out.println(son.getHeritage());
}
출력 : 1000
위의 Son 클래스는 Mother를 extends 하는 것 말고는 내부에 아무런 변수나 메서드가 정의되어있지 않습니다.
하지만 위의 테스트 코드는 정상적으로 동작합니다(son.getHeritage()) 왜그럴까요??
이는 바로 부모 클래스로부터 속성인 heritage와 메서드인 getHeritage()를 상속받았기 때문입니다!
public class OverLoadingTest {
class Mother{
int heritage = 1000;
int getHeritage(){
return this.heritage;
}
}
class Son extends Mother{
@Override
int getHeritage() {
return 1500;
}
}
@Test
void test(){
Son son = new Son();
System.out.println(son.getHeritage());
}
}
출력 : 1500
위의 경우에는 왜 1500원이 출력될까요? 이는 바로 부모로 부터 물려받은 getHeritage()라는 메서드를 재정의
하여 사용하였기 때문입니다
아직 어노테이션이 뭔지 모르신다면 @Override
가 뭔지 모르실것 같아 간단히 설명드리면, 우선은 저러한 것을 적지 않아도 정상적으로 override 가능합니다.
하지만 @Override를 적을 시에는 오버라이딩이 잘못도 경우 경고를 줍니다
ex) 라이브러리 중 하나가 업데이트되어 상속하는 클래스 메서드의 시그니처가 바뀌었다, 이때 이 어노테이션을 적용하지 않았다면 오버라이드 한 메서드가 업데이트 이후 그냥 추가적인 메서드로 인식되어 컴파일 오류가 발생하지 않습니다.
하지만 이러한 어노테이션을 적용함으로서 컴파일 오류를 일으켜 작동방식이 바뀌는 것을 대비할 수 있고, 코드를 살펴보았을 때 다른 개발자라도 해당 메서드가 오버라이딩하였다는 것을 쉽게 파악할 수 있습니다.
'JAVA' 카테고리의 다른 글
StringBuffer,StringBuilder의 개념 및 차이점 정복하기 (0) | 2023.05.17 |
---|---|
문자열 리터럴 할당 VS new String() (0) | 2023.05.10 |
[JAVA] Enum 클래스 정복하기! (0) | 2023.05.10 |
[JAVA] 클래스 변수, 지역 변수, 인스턴스 변수란? (0) | 2023.05.09 |
[JAVA] 기본형과 참조형에 대해 알아보자! (0) | 2023.05.09 |