안녕하세요. J4J입니다.
이번 포스팅은 오버라이딩과 오버로딩에 대해 적어보는 시간을 가져보려고 합니다.
오버라이딩(overriding)
오버라이딩이란 부모 클래스에서 사용되고 있는 메서드들을 자식 클래스에서 재 정의한 것을 의미합니다.
자바로 프로그래밍을 하시다 보면 메서드 위에 @override라는 어노테이션을 본 적이 있으실 건데 이런 어노테이션이 붙어있는 메서드들이 모두 오버라이딩된 메서드들입니다.
오버라이딩을 사용하는 목적은 무엇일까요?
그 이유는 프로그래밍을 하다 보면 부모와 자식 클래스 모두 동일한 메서드 명을 사용해야 될 경우가 존재하는데 자식 클래스 입장에서는 부모 클래스와 다른 결과물을 보여주고 싶을 때가 있습니다.
실생화에서 예를 들어보면 10년 전에 부모님이 집을 소유하고 있었는데 집의 종류는 아파트였습니다.
부모님이 돈이 많아서 최근에 자식에게 아파트를 상속시켜줬는데 자식 입장에서는 아파트가 살기 싫을 수 있겠죠?
그래서 자식은 상속받은 아파트를 판매하여 전원주택으로 이사를 가게 되었습니다.
그럼 10년 전의 부모님과 현재의 자식에게 현재 살고 있는 집의 종류가 무엇입니까? 라고 물어보면 부모님은 아파트에 산다고 하고 자식은 전원주택에 산다고 할 수 있습니다.
이 처럼 부모와 자식 모두 똑같은 질문(메서드)이지만 다른 결과가 만들어지게 되는데 이때 오버라이딩을 사용하게 됩니다.
오버라이딩 사용 방법
오버라이딩을 사용하기 위해서는 총 5가지의 조건이 필요합니다.
- 메서드 이름이 동일
- 파라미터 형태 동일
- 리턴 형태 동일
- 접근 제한자는 부모 클래스보다 더 범위가 넓게 (private < default < protected < public)
- 자식 클래스가 소유하고 있는 예외처리는 모두 부모 클래스가 소유
※ 접근 제한자에 대해 모르겠다면? [Java] 자바기초 - 접근 제한자
해당 조건들 중 하나라도 어기게 된다면 오버라이딩을 할 때 에러가 발생이 되는데 보통 부모의 모습과 완전 동일한 형태의 메서드로 오버라이딩하기 때문에 위의 문제들이 발생할 일은 드물 겁니다.
위에서 말씀드린 내용을 기반으로 하여 코드를 작성해보겠습니다.
package override_overload;
public class OverrideParents {
public void whoami() {
System.out.println("OverrideParents 입니다.");
}
protected void myHouse() {
System.out.println("나의 집은 25평 아파트입니다.");
}
public static void main(String[] args) {
OverrideParents overrideP = new OverrideParents();
overrideP.whoami(); // OverrideParents 입니다.
overrideP.myHouse(); // 나의 집은 25평 아파트입니다.
}
}
package override_overload;
public class OverrideChild extends OverrideParents {
@Override
public void whoami() { // 일반적인 오버라이드
System.out.println("OverrideChild 입니다.");
}
@Override
public void myHouse() { // 더 높은 접근제한자로 변경하여 오버라이드
System.out.println("나의 집은 50평 전원주택입니다.");
}
public static void main(String[] args) {
OverrideChild overrideC = new OverrideChild();
overrideC.whoami(); // OverrideChild 입니다.
overrideC.myHouse(); // 나의 집은 50평 전원주택입니다.
}
}
보시는 것처럼 기본적으로 상속이라는 개념이 필수적이고 오버라이딩 되는 메서드들에는 @override라는 어노테이션을 보실 수 있습니다.
어? 그럼 @override가 없는 것들은 오버 라이딩된 것이 아닌가요?
대답은 No입니다.
@override는 특별히 어떤 역할을 해주는 것이 아니라 프로그래머들이 쉽게 확인할 수 있도록 단순히 표시해둔 것이라고 생각하시면 됩니다.
그리고 코드를 보시면 whoami()나 myHouse()와 같이 부모가 소유하고 있던 메서드들을 자식들이 그대로 호출을 하게 되는데 오버라이딩이 된 메서드들이기 때문에 서로 다른 결과물을 보여주는 걸 확인하실 수 있습니다. (오버라이딩 된 메서드가 아니라면 부모 클래스에서 정의된 결과가 나와야 됩니다.)
오버로딩(overloading)
오버로딩이란 같은 이름의 메서드들이 서로 다른 역할을 수행할 수 있도록 만들어주는 것을 의미합니다.
오버로딩은 오버라이드와 달리 @override 같은 어노테이션이 존재하지 않고 단순히 메서드명만 동일하게 하여 서로 다른 파라미터, 서로 다른 리턴 타입을 새롭게 정의하면 됩니다.
오버로딩을 사용하는 이유는 무엇일까요?
그 이유는 목적은 서로 같으나 파라미터 타입이 달라 에러가 발생되는 것을 방지하기 위해 사용합니다.
예를 들어 계산기의 덧셈 동작을 만들고 싶을 때 겉으로만 봤을 때는 5+3을 하든 3.2+4.7을 하든 숫자+숫자를 해주는 것으로 보입니다.
하지만 데이터적인 관점으로 봤을 때는 5+3과 3.2+4.7은 데이터 타입이 서로 다릅니다. (5+3은 int, 3.2+4.7은 double)
이런 경우 덧셈을 하기 위해 들어오는 파라미터 타입이 다르기 때문에 int에 대해서만 메서드가 정의되어 있다면 double로 들어왔을 때는 덧셈 기능을 수행할 수 없게 되는 겁니다.
오버로딩 사용 방법
오버로딩을 사용하기 위해서는 2가지 조건이 필요합니다.
- 메서드 이름이 동일
- 파라미터를 서로 다르게 조합
오버로딩은 오버라이딩과 달리 단순히 이 2가지 조건만 지켜주게 된다면 문제없이 사용할 수 있습니다.
오버로딩에 대해 말씀드린 것들을 코드로 작성해보겠습니다.
package override_overload;
public class OverloadClass {
public void whatData(String stringVal) {
System.out.println(stringVal + "은(는) 문자열 타입입니다.");
}
public void whatData(int intVal) {
System.out.println(intVal + "은(는) 정수 타입입니다.");
}
public int add(int intVal, int intVal2) {
return intVal + intVal2;
}
public double add(double doubleVal1, double doubleVal2) {
return doubleVal1 + doubleVal2;
}
public static void main(String[] args) {
OverloadClass overload = new OverloadClass();
overload.whatData("하이염"); // 하이염은(는) 문자열 타입입니다.
overload.whatData(32); // 32은(는) 정수 타입입니다.
System.out.println(overload.add(5, 3)); // 8
System.out.println(overload.add(3.2, 4.7)); // 7.9
}
}
보시다시피 동일한 메서드를 이용하여 데이터 타입을 구분해야 되거나 위에서 말씀드린 덧셈 기능을 만들고 싶을 때 오버로딩을 사용하게 됩니다.
이 뿐만 아니라 생성자를 만들 때도 오버로딩이 적용됩니다.
동일한 명의 생성자인데 파라미터가 무엇인지에 따라 다른 결과를 수행하기 때문에 오버로딩이라고 할 수 있습니다.
※ 생성자에 대해 모른다면? [Java] 자바기초 - 생성자(Constructor)
정리
이상으로 오버라이딩과 오버로딩에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Language > Java' 카테고리의 다른 글
[Java] 자바기초 - 객체지향(OOP) - 추상화(Abstraction) (0) | 2020.12.23 |
---|---|
[Java] 자바기초 - 객체지향(OOP) - 캡슐화(Encapsulation) (0) | 2020.12.22 |
[Java] 자바기초 - 추상클래스와 인터페이스(abstract/interface) (0) | 2020.12.21 |
[Java] 자바기초 - 접근 제한자 (0) | 2020.12.16 |
[Java] 자바기초 - 생성자(Constructor) (0) | 2020.12.14 |
댓글