데이터 과학

메소드 오버로딩 본문

프로그래밍 언어론/JAVA 기초

메소드 오버로딩

티에스윤 2022. 11. 5. 23:46

오버로딩을 사용하면 여러 개의 메소드 이름을 사용하지 않아도 됩니다. 

무엇보다 하나의 이름만 알고 있으면서 여러 개의 메소를 나열하지 않아도 되는 것입니다. 

 

오버로딩을 사용하지 않는 예제를 보면 다음과 같습니다. 

 

public class OverloadingTest2 { 
 public static void main(String args[]) { 
 Overloading2 over2 = new Overloading2(); 
 System.out.println(over2.addint(3,3)); 
 System.out.println(over2.addintdouble(3,3.0)); 
 System.out.println(over2.adddouble(3.0,3.0)); 
  }
 } 
 
class Overloading2 { 
  int addint(int a, int b){
    return a+b;
 }
double addintdouble(int a, double b){
    return a+b;
 }
double adddouble(double a, double b){
    return a+b;
 }

 

 

오버로딩을 사용하는 예제로 바뀌어 보았습니다. add 메소드 하나만 만들어서 사용합니다. 

아무래도 여러개의 메소드를 외울 필요가 없어서 편하겠지요. 

 

public class OverloadingTest2 { 
 public static void main(String args[]) { 
 Overloading2 over2 = new Overloading2(); 
 System.out.println(over2.add(3,3)); 
 System.out.println(over2.add(3,3.0)); 
 System.out.println(over2.add(3.0,3.0)); 
  }
 } 
 
class Overloading2 { 
  int add(int a, int b){
    return a+b;
 }
double add(int a, double b){
    return a+b;
 }
double add(double a, double b){
    return a+b;
 }

 

 

실행결과

6
6.0
6.0

 

 

그렇다면 다음과 같은 예제들을 작성하면 오버로딩이 성립할까요? 

결론은 안됩니다. 그 이유는 매개변수(parameter)의 성향이 같으면 변수 이름이 달라도 오버로딩이 성립하지 않습니다. 

 

보기1)

int add(int a, int b) { return a+b; }

int add(int x, int y) { return x+y; }

 

위의 두 메쏘드는 매개변수의 이름만 다를 뿐 매개변수의 타입이 같기 때문에 오버로딩이 성립하지 않습니다.

매개변수의 이름이 다르면 메쏘드 내에서 사용되는 변수의 이름이 달라질 뿐, 아무런 의미가 없습니다.

이 두 메쏘드는 정확히 같은 것입니다. 마치 수학에서, f(x) = x + 1과 f(a) = a + 1이 같은 표현인 것과 같습니다.

컴파일하면, 'add(int,int) is already defined(이미 같은 메쏘드가 정의되었다).'라는 메시지 가 나타납니다.

 

 

보기2)

int add(int a, int b) { return a+b; }

long add(int a, int b) { return (long)(a + b); }

 

보기2는 리턴 타입만 다른 경우입니다. 매개변수의 타입과 개수가 일치하기 때문에, add(3,3)과 같이 호출하였을 때 어떤 메쏘드가 호출된 것인지 결정할 수 없기 때문에 오버 로딩으로 간주되지 않습니다.

이 경우 역시 컴파일하면, 'add(int,int) is already defined'라는 메시지가 나타납니다.

 

 

보기3)

long add(int a, long b) { return a+b; }

long add(long a, int b) { return a+b; }

 

두 메소드 모두 int형과 long형 매개변수가 하나씩 선언되어 있지만, 서로 순서가 다른 경우입니다.  호출 시 매개변수의 값에 의해 호출될 메소드가 구분될 수 있으므로 중복된 메소드 정의가 아니며 오버로딩으로 간주합니다.

이처럼 단지 매개변수의 순서만을 다르게 하여 오버로딩을 구현하면, 사용자가 매개변수의 순서를 외우지 않아도 되는 장점이 있지만, 오히려 단점이 될 수도 있기 때문에 주의해야 합니다.

예를 들어 add(3,3L)과 같이 호출되면 첫 번째 메소드가, add(3L, 3)과 같이 호출되면 두 번째 메소드가 선택됩니다. 이 경우에는 add(3,3)과 같이 호출할 수 없습니다. 이와 같이 호출할 경우, 두 메쏘드 중 어느 메쏘드가 호출된 것인지 알 수 없기 때문에 메소드를 호출하는 쪽에서 컴파일 에러가 발생한다.

 

보기4)

int add(int a, int b) { return a+b; }

long add(long a, long b) { return a+b; }

int add(int[] a) {

   for(int i=0,result=0; i < a.length; i++) {

       result += a[i];

    }

return result;

}

 

이 예제는 오버로딩이 성립합니다. 정의된 매개변수가 서로 다르지만 메소드 모두 매개변수로 넘겨받은 값을 더해서 그 결과를 리턴합니다. 

 

 

 

 

다음 예제는 조금 더 길게 작성한 메소드 오버로딩에 대한 예제입니다.

 

public static void main(String args[]) {

    Overloading over = new Overloading();

    System.out.println("over.add(3, 3) 결과:" + over.add(3,3));

    System.out.println("over.add(3L, 3) 결과: " + over.add(3L,3));    // L은 long형입니다. long은 정수형입니다. 

    System.out.println("over.add(3, 3L) 결과: " + over.add(3,3L));

    System.out.println("over.add(3L, 3L) 결과: " + over.add(3L,3L));

        int[] a = {100, 200, 300};

     System.out.println("over.add(a) 결과: " + over.add(a));

     }

}

 

 

class Overloading {

   int add(int a, int b) {                      // 정수 매개변수 2개가 값에 의한 전달 됩니다. 

    System.out.print("int add(int a, int b) - ");

       return a+b;

}

 

   long add(int a, long b) {                     // 정수형,  long 정수형 순서로 매개변수 1개씩 값에 의한 전달됩니다. 

    System.out.print("long add(int a, long b) - ");

     return a+b;

}

 

   long add(long a, int b) {                       // 매개변수 순서가 중요합니다. long 정수형과 int형 순서로 값을 받습니다.

    System.out.print("long add(long a, int b) - ");

     return a+b;

}

 

   long add(long a, long b) {                    // long long으로 매개변수를 설정합니다. 

    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;

  }

}

 

결과: 

 

int add(int a, int b) - over.add(3, 3) 결과:6
long add(long a, int b) - over.add(3L, 3) 결과: 6
long add(int a, long b) - over.add(3, 3L) 결과: 6
long add(long a, long b) - over.add(3L, 3L) 결과: 6
int add(int[] a) - over.add(a) 결과: 600

 

 

간단한 예제를 하나 더 봅시다. 

 

 

public class A {
   void test(int i) { System.out.println("1"); }
   void test(double i) { System.out.println("2"); }
 

public static void main(String [] args) {
    A a = new A();
   a.test(1.0);
   a.test(1);
  }

 

 

결과:

 

2
1

'프로그래밍 언어론 > JAVA 기초' 카테고리의 다른 글

추상 클래스와 오버라이딩  (4) 2022.11.13
상속(Inheritance)  (10) 2022.11.06
생성자 (constructor)  (8) 2022.10.30
배열 (array)  (1) 2022.10.23
return에 대하여 이해하기  (0) 2022.09.10