[JAVA] JAVA 오버로딩, 오버라이딩 기초 정리
이번엔 JAVA 의 오버로딩(Overloading)과 오버라이딩(Overriding)에 대해서 알아보고자 합니다.
오버로딩(Overloading) 이란?
overload
의 사전적인 의미는 과적하다라는 뜻을 지니고 있습니다. 그래서 JAVA 에서도 이를 차용해서 이름이 같은 여러개의 메소드가 하는 일은 같지만 다양한 방식으로 호출할 수 있습니다.
JAVA 의 오버로딩은 메소드와 생성자에 적용이 됩니다.
오버로딩 사용의 이점
오버로딩을 사용하면 코드의 가독성과 재사용성을 높일 수 있습니다. 같은 이름의 메소드를 여러 개 정의하여 다양한 상황에서 사용할 수 있습니다.
오버로딩의 조건
- 메소드의 경우 한 클래스 내에서 메소드 명이 동일해야 합니다.
- 매개 변수의 개수 또는 타입이 달라야 합니다. (매개 변수의 타입은 동일하고 순서도 동일하지만 이름이 다를 경우는 같다고 인식하므로 주의해야 합니다.)
다음은 오버로딩의 예제 코드입니다
public class MathUtils {
public int add(int a, int b) {
return a+b;
}
public double add(double a, double b) {
return a+b;
}
}
오버로딩 사용 시 주의 사항
제가 일을 하면서 겪었었던 것으로 제가 일하는 곳에서의 코드에서 메소드가 오버로딩되어 있었는데 실제로 동작을 하는 메소드가 따로 있고, 해당 메소드를 오버로딩하여 최종적으로는 실제 수행되는 메소드를 부르도록 설계 되어 있었는데 굉장히 심각한 문제가 있었습니다.
이는 아래 예시 코드를 통해서 좀 더 자세히 알아보도록 하겠습니다.
public void analyze(int a){
analyze(a, 0.1, "test");
}
public void analyze(double b) {
analyze(1, b, "test");
}
...
public void analyze(int a, double b, String c) {
// 코드 수행
}
제가 다니던 회사에서는 위와 같이 analyze 라는 메소드가 실제로 수행되는 곳은 따로 있으며, 매개 변수 개수 별로 실제 수행 되는 메소드를 부르도록 되어 있는 구조로 되어있었습니다.
위와 같은 구조일 경우에는 심각한 문제가 존재하는데 그 문제는 실제로 어떤 작업이 수행되는 마지막 메소드에 새로운 매개변수가 추가가 될 경우 해당 메소드를 부르는 곳이 모두 수정이 되어야 한다는 문제가 존재했었습니다.
아마도 이 구조를 처음 생각한 사람은 매개 변수 별로 실행이 되도록 해야한다는 요구 사항이 있었던 것 같습니다. 하지만 위와 같은 구조는 정말로 지양해야 하며, 실행에 필요한 매개변수를 담는 클래스를 사용한다던지 하는 등의 범용성 있는 방법을 택했어야 합니다.
위 코드의 더 심각한 문제는 만약 위 코드로 구현된 모듈을 다른 모듈이 불러서 사용할 경우에 발생합니다. 위 코드를 사용하는 모듈에서 마지막 analyze 메소드가 바뀌게 된다면 위 코드를 사용하는 모듈을 사용하는 다른 모듈들 모두 수정이 되어야 해서 단순히 매개 변수 하나 추가하는데 정말 많은 작업을 해야하고, 추가로 오류 검증 시간도 굉장히 많이 필요해 지게 됩니다.
저는 위와 같은 문제를 메소드에서 필요로 하는 매개 변수들을 필드로 가지는 클래스를 메소드의 매개 변수로 받도록 수정하였습니다.
public class Parameters{
public int a = 1;
public double b = 0.1;
public String c = "test";
}
public void analyze(Parameters parameters) {
// 코드 수행
}
public static void main(String args[]) {
Parameters parameters = new Parameters();
analyze(parameters);
}
매개 변수가 되는 Parameters 클래스의 필드들은 어차피 실제 실행되는 메소드를 부를 때 넘겨주는 매개 변수들이므로 자유롭게 변경할 수 있게 접근 제한자를 public 으로 해주었습니다. public 으로 하면 Parameters 클래스의 객체 선언 후에도 필드들을 자유자재로 수정할 수 있습니다.
또한 Parameters 클래스의 필드들에는 미리 초기화를 시켜놨는데 이는 사용자가 단지 Parameters 객체만 생성하고 굳이 다른 작업을 해주지 않아도 analyze 메소드를 실행할 수 있게 하기 위함입니다. 만약에 다른 값이 들어가야 한다면 Parameters 객체의 필드들을 수정하면 됩니다.
일단 저는 위와 같이 변경을 했습니다만 제가 한 방법이 정답도 아니거니와 틀릴 수도 있습니다 하지만 제 상급자와 논의를 해서 그나마 위 방법이 좀 더 효율적이라고 판단을 하여 위와 같이 적용을 했었습니다.
오버라이딩(Overriding) 이란?
override 는 사전적 의미로 덮어쓰다라는 뜻을 가지고 있습니다. 그래서 JAVA 에서는 부모 클래스로부터 상속 받은 이미 정의된 메소드를 자식 클래스에서 재정의 하는 것을 말합니다. 그래서 오버라이딩을 하면 부모 클래스의 메소드가 아닌 자식 클래스의 재정의한 메소드가 실행이 되게 됩니다.
제 생각엔 오버라이딩은 생각보다 많이 사용되는 것 같습니다. 아마도 상속이 많이 사용되며, 재사용성을 극대화해서 새로운 메소드의 추가를 최대한 자제하기 위해서 그런게 아닌가 해서 그런 것 같습니다.
오버라이딩 사용 조건
@Override
라는 어노테이션을 사용해야 합니다.- 매개변수의 타입, 개수, 순서가 일치해야 합니다.
- 리턴 타입이 동일해야 합니다.
- 접근 제한자는 부모 클래스의 메소드와 같거나 더 넓은 범위어야 합니다.
- 부모 클래스의 메소드의 예외와 같거나 예외의 개수를 줄일 수 있습니다.
오버라이딩의 사용 예는 다음과 같습니다.
class Person{
void print() {
System.out.println("Person 클래스의 print() 메소드");
}
}
class Student extends Person{
@Override
public void print() {
System.out.println("Student 클래스의 print() 메소드");
}
}
public class Test{
public static void main(String[] args) {
Person p = new Person();
Student st = new Student();
p.print();
st.print();
}
출력결과
Person클래스의 print() 메소드
Student클래스의 print() 메소드
}
마치며
오버로딩과 오버라이딩에 대해 기초적인 내용을 정리해 보았습니다.
포스트 읽어주셔서 감사드리며, 잘못된 내용이나 오타 혹은 궁금하신 내용이 있으시면 댓글 부탁드리겠습니다.
Comments