brunch

You can make anything
by writing

C.S.Lewis

by 김경민 May 04. 2016

overloading vs. overriding

 



"오버로딩과 오버라이딩의 차이점을 설명해보세요."




IT분야로 취업을 희망하는 대학생들은 반드시 넘겨야 할 전공면접(실무면접)에서 단골 문제중 하나로 알려져있다. 나는 학부 시절 전공 수업을 통해서 이것을 분명히 배웠고 개념을 어렴풋이 이해하고는 있지만,

지금 당장 이 질문을 받는다면 명료하게 말로 표현하기 힘들것 같다.



Java를 처음 접했을 때, 오버라이딩과 오버로딩은 용어가 참으로 헷갈렸다.

아마 이 개념이 헷갈리는 이유는 'over'라는 접두사 때문이 아니었나 싶은데..뭐, 암튼.



누군가가 이 질문을 우리에게 한다면, 이것만큼은 당당하고 똑부러지게 대답해보자.

그래서 Java로 작성한 예제를 통해 다시 한번 개념을 떠올려보고, 정리를 해보았다.



우선,

오버로딩(overloading)은 이름은 같지만 시그니처(파라미터 수, 타입) 데는 다른 메소드를 중복으로 선언하는 것을 의미하고, 오버라이딩(overriding)은 부모 클래스의 메소드의 동작 방법을 변경(재정의)하여 우선적으로 사용하는 것이다.

(그래그래..이렇게 배웠었지..)







1. 오버로딩(overloading)


오버로딩은 같은 메소드라도 매개변수만 다르면 얼마든지 정의하고 사용할 수 있다.


특징:

1) 메소드 이름이 같아야 한다.

2) 리턴형이 같아도 되고 달라도 된다.

3) 파라미터 개수가 달라야 한다 .

4) 파라미터 개수가 같을 경우, 데이터타입이 달라야 한다.

* 리턴타입은 시그니처에 포함되지 않기 때문에 주의. 컴파일 에러 발생.




아래의 예제에서 처럼 test() 함수는 3가지 종류를 선언했고, 매개변수에 따라 해당 메소드가 실행된다.


[ Overloadingtest.java ]

public class Overloadingtest {

    // test() 호출
    void test(){
        System
.out.println("매개변수 없음");
    }
    
    // test에 매개변수로 int형 2개 호출
     void test(int a, int b){
        System
.out.println("매개변수 "+ a + "와  " + b);
    }
    
    // test에 매개변수 double형 1개  호출
    void test(double d){
         System
.out.println("매개변수 " + d);
    }
}




[ OverloadingExample.java ]

public class OverloadingExample {

    public static void main(String
[] args) {
   
        Overloadingtest ob = new Overloadingtest();
         
        // test()  호출
        ob.test();
         
        // test(int a, int  b) 호출
        ob.test(10, 20);
         
        // test(double d)  호출
        ob.test(50);
        
        // test(double d) 호출
         ob.test(123.4);
    }
}


>> 실행결과

매개변수 없음

매개변수 10와 20

매개변수 50.0

매개변수 123.4


예제에서와 같이 test 라는 같은 이름의 메소드를 여러개 정의하고 매개변수만 변경하여 선언했을 때, 호출 매개변수에 따라 매칭되어 해당 함수를 실행시킨다.








2. 오버라이딩(overriding)


상속 관계에 있는 클래스 간에 같은 이름의 메소드를 정의하는 기술이다.

만약 자식클래스가 부모클래스에서 선언된 것과 같은 메소드를 가질 때, 메소드 오버라이딩이라고 한다.


특징:

1) 오버라이드 하고자 하는 메소드가 상위 클래스에 존재해야 한다.

2) 메소드 이름이 같아야 한다.

3) 메소드 파라미터 개수, 파라미터의 자료형이 같아야 한다.

4) 메소드 리턴형이 같아야 한다.

5) 상위 메소드와 동일하거나 내용이 추가되어야 한다.




아래의 예제에서, People에 print()함수를 선언하고, Student에서 People을 상속하여 print() 메소드를 재정의 하였다. main 함수에서 Student 객체를 생성 후, print() 메소드를 호출하면 오버라이딩된 Student 객체의 print() 메소드가 호출 된다.


[ People.java ]

public class People {
    
    public String name;
    public int age;
   
    public void print(){
        System
.out.println("이름은 "+this.name+ "이고,  나이는" + this.age+"입니다.");
     }   
}



[ Student.java ]

// People 상속
public class Student extends People {
    
    
String job;


    // print() 메소드  오버라이딩
    public void print(){
        System
.out.println("이름은 "+this.name + "이고,  나이는" + this.age + "입니다.");
        
//새롭게 추가된 부분

        System.out.println(this.name+"은  "+this.job+"  입니다."); 
    }
}



[ OverridingExample.java ]

public class OverridingExample {

    public static void main(String[] args) {
        
      Student st = new Student();


      st.name = "KKM";
      st.age = 25;
      st.job= "취준생";
        

      // Overriding된 Manager객체의  print()호출
      lee.print();
    }
}


>> 실행결과

사원의 이름은 KKM이고, 나이는 25입니다.

관리자 KKM은 취준생 입니다.




주로 이렇게 하는 이유는 하나의 코드로 여러 객체를 처리할 수 있다는 장점이 있기 때문이다.

예를 들면,


class A {

    public void cal() {

        System.out.println("부모 A의 cal() 함수 실행");

    }

}

class B extends A {

    public void cal() {

        System.out.println("자식 B의 cal() 함수 실행");

    }

}

class C extends A {

    public void cal() {

        System.out.println("자식 C의 cal() 함수 실행");

    }

}

public class Overriding {

    public static void main(String[] args) {

        List<A> list = new ArrayList<A>();

        list.add(new A());

        list.add(new B());

        list.add(new C());

        for(a a : list) {

            a.cal();

        }

    }

}


>> 실행결과

부모 A의 cal() 함수 실행

자식 B의 cal() 함수 실행

자식 C의 cal() 함수 실행



A를 상속받은 클래스가 B, C가 있고 cal() 함수를 재정의 하였다. 객체를 List에 담아 두었다가 for문을 돌면서 한번에 cal()기능을 수행하고 싶은데 객체마다 기능이 조금씩 다르다. 그럴때 상속받아서 재정의한 후 부모 클래스의 함수를 호출하면 객체별로 재정의한 함수를 수행할 수 있는 것이다.






정리!


오버로딩(overloading)은 한 클래스 내에, 여러 개의 같은 이름의 메소드를 정의하는 것을 말한다. 이렇게 메소드의 이름을 동일하게 만들어 프로그램의 가독성을 증가시킬 수 있다는 장점이 있다.


오버라이딩은(overriding)은 부모로부터 받은 메소드의 로직(내부)을 입맛에 맞게 변경하는 것이다. 객체지향 언어의 특징인 다형성 중 하나이다.


매거진의 이전글 소프트웨어 개발자를 위한 Callback의 정석.
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari