[자바/Java] 오버로딩(Overloading) 이란?

resilient

·

2021. 8. 3. 16:31

728x90
반응형

 

자바는 OOP 즉, 객체 지향 언어이다.

OOP의 큰 장점이자 OOP에서 가장 중요한 개념 중 하나로는 다형성(Polymorphism)이 있다. 

다형성은 각 요소들이 여러 가지 자료형으로 표현될 수 있다는 것을 말한다.

이번에는 자바에서 다형성을 띄고 있는 것들 중 '오버 로딩'에 대해서 정리해보려고 한다.

 

오버 로딩이란?

오버 로딩은 한 클래스 내에 같은 이름의 메서드를 여러 개 정의해서 사용하는 것을 의미한다.

메서드 오버 로딩도 같은 말이다.

 

오버로드는 말 그대로 한 곳에 여러 개를 과적하다, 많이 싣다 라는 의미를 가지고 있는데

하나의 메서드로 여러 기능을 구현하기 때문에 붙여진 이름이다.

 

오버 로딩의 조건은 아래와 같다.

  • 메서드 이름이 같아야 하고
  • 매개변수의 개수 또는 타입이 달라야 한다.

 

오버 로딩의 장점

그럼 왜 오버 로딩을 쓰는 걸까? 장점이 있으니까 쓰지 않을까?

 

그럼 장점에는 뭐가 있을까?

  • 메서드 이름을 같게 하면, 같은 기능을 하는 메서드들을 하나의 이름으로 사용할 수 있다.
  • 메서드의 Naming, 즉 메서드 이름을 절약할 수 있다. 

 

물론 장점만 있는 것은 아니다.

오히려 메서드의 이름이 같으면 자신이 작성한 코드를 헷갈려 할 수 있다는 단점도 존재한다.

 

오버 로딩의 예시

class OverloadingTest {
	public static void main(String args[]) {
		MyMath3 mm = new MyMath3();
		System.out.println("mm.add(3, 3) 결과:"    + mm.add(3,3));
		System.out.println("mm.add(3L, 3) 결과: "  + mm.add(3L,3));
		System.out.println("mm.add(3, 3L) 결과: "  + mm.add(3,3L));
		System.out.println("mm.add(3L, 3L) 결과: " + mm.add(3L,3L));

		int[] a = {100, 200, 300};
		System.out.println("mm.add(a) 결과: " + mm.add(a));
   }
}

class MyMath3 {
	int add(int a, int b) {
		System.out.print("int add(int a, int b) - ");
		return a+b;
	}
	
	long add(int a, long b) {
		System.out.print("long add(int a, long b) - ");
		return a+b;
	}
	
	long add(long a, int b) {
		System.out.print("long add(long a, int b) - ");
		return a+b;
	}

	long add(long a, long b) {
		System.out.print("long add(long a, long b) - ");
		return a+b;
	}

	int add(int[] a) {		// 배열의 모든 요소의 합을 결과로 돌려준다.
		System.out.print("int add(int[] a) - ");
		int result = 0;
		for(int i=0; i < a.length;i++) {
			result += a[i];
		}	
		return result;
	}
}

 

위에 코드를 보면 MyMath3 클래스에 add 메서드가 오버 로딩되어있고, add라는 같은 메서드에 안에 파라미터의 개수와 타입이 다 다르게 메서드 오버 로딩을 사용한 것을 알 수 있다.

 

 

메서드 오버 로딩을 사용할 때 주의할 점은, 오버 로딩된 메서드들은 매개변수에 의해서만 구별될 수 있다는 점이다.

반환 타입 return 값은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.

 

이러한 이유로 메소드 오버 로딩을 사용하면 사람이 자신의 코드를 헷갈릴 순 있어도 JVM이 컴파일할 때는 메서드들을 헷갈리지 않고 에러 없이 실행할 수 있다.

 

가변 인자(varargs)와 오버 로딩

 

기존에는 메서드의 매개변수 개수가 고정적이었으나, 지금은 동적으로 지정해줄 수 있게 되었고,

이 기능을 가변 인자라고 한다.

가변 인자는 '타입,,, 변수명'과 같은 형식으로 선언한다.

가변 인자와 매개 변수를 파라미터에 같이 사용할 경우에는, 가변 인자를 파라미터 중 맨 마지막에 선언해줘야 한다.

그렇지 않으면 가변 인자인지 아닌지를 구별할 방법이 없기 때문에 컴파일 에러가 발생한다.

 

 

아래 메서드를 사용해서 예시를 살펴보자.

String concatenate(String ... str){...}

 

위 메서드를 호출할 때는 아래와 같이 인자의 개수를 가변적으로 사용할 수 있다.

맨 마지막 예시처럼 배열도 인자가 될 수 있다.

 

System.out.println(concatenate("", "100", "200", "300"));
System.out.println(concatenate("-", strArr));
System.out.println(concatenate(",", new String[]{"1", "2", "3"}));
System.out.println("["+concatenate(",", new String[0])+"]");
System.out.println("["+concatenate(",")+"]");

 

가변 인자는 내부적으로 배열을 이용하기 때문에 가변 인자가 선언된 메서드를 호출할 때마다 배열이 새로 생긴다.

이런 이유로 인해 인자가 존재하지 않아도 된다. 존재하지 않으면 배열이 생기지 않을 뿐이기 때문이다.

 

이런 식으로 비효율성이 존재하기 때문에 꼭 필요한 경우에만 가변 인자를 사용해야 한다.

 

또한 가변인자를 선언한 메서드를 오버 로딩하면, 메서드를 호출했을 때 JVM이 구별하지 못하는 경우가 발생하기 쉽기 때문에 이런 경우에는 가능하면 오버 로딩을 사용하지 않는 게 좋다.

 

 

 

 

 

본 게시물은 '자바의 정석'을 바탕으로 공부한 내용을 정리한 것입니다.

오류가 있거나 궁금하신 점은 댓글로 말씀해주시면 감사하겠습니다.

 

 

반응형

'Language > Java & Kotlin' 카테고리의 다른 글

[자바/Java] Static 이란?  (4) 2022.03.16
[자바/Java] 인터페이스(Interface) 란?  (0) 2021.08.09
[자바/Java] 생성자 란?  (0) 2021.08.02
[자바/Java] 람다식이란?  (0) 2021.03.06
[자바/Java] 제네릭이란?  (0) 2021.02.27