Java - 오버로딩(overloading), 오버라이딩(overriding) 차이점
오버로딩(Overloading)
오버로딩(Overloading)이라는 뜻은 사전적으로 '과적하다.'라는 뜻입니다. C언어에서는 함수명이 고유하게 존재해야 합니다. 즉 하나의 함수가 하나의 기능만을 구현해야 한다는 것입니다. 하지만 자바에서는 하나의 메소드 이름으로 여러 기능을 구현하기 때문에 '과적하다.'라는 뜻의 이름을 붙여준 것으로 보입니다.
⭐️ 자바의 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메소드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메소드를 정의할 수 있습니다.
오버로딩의 조건
메소드의 이름이 같고, 매개변수(파라미터)의 개수나 타입이 달라야 합니다. 주의할 점은 '리턴 값만' 다른 것은 오버로딩을 할 수 없습니다.
접근 제어자도 자유롭게 지정해 줄 수 있다. 각 메소드의 접근 제어자를 public, default, protected, private으로 다르게 지정해줘도 상관없다는 것이다. 접근 제어자만 다르게한다고 오버로딩이 가능하지 않습니다.
⭐️ 즉 , 오버로딩은 매개 변수(파라미터)의 개수 혹은 타입의 차이로만 구현할 수 있습니다.
오버로딩을 사용하는 이유
1. 같은 기능을 하는 메소드를 하나의 이름으로 사용할 수 있습니다.
우리가 흔히 콘솔창에 텍스트를 출력할 때 사용하는 println라는 메소드를 대표적인 예로 들어볼 수 있습니다. 실은 이 함수가 오버로딩의 결정체입니다. 우리는 println의 인자(아규먼트) 값으로 int, double, boolean, String 등의 아주 다양한 타입의 값들을 집어넣어도 우리는 그 함수들이 어떻게 실행되지는 모르지만 콘솔창에 아주 잘 출력해주는 것을 볼 수 있습니다.
이렇게 '출력하다.'라는 같은 기능을 가진 메소드들을 println이라는 하나의 이름으로 정의가 가능한 것입니다.
2. 메소드의 이름을 절약할 수 있다.
이 위에서 예로 들었던 println을 생각해보면, 이 메소드를 매개변수의 종류에 따라서 다르게 지정한다고 생각해봅시다. printlnInt, printlnDouble, printlnBoolean 등 많은 메소드들의 이름을 정해줘야 할 것입니다. 이는 메소드의 이름을 어떻게 지을지 엄청나게 고민을 해야하고, 많은 시간 낭비를 불러옵니다.
오버라이딩(Overriding)
부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의하는 것을 오버라이딩이라고 합니다. 상속받은 메소드를 그대로 사용할 수도 있지만, 자식 클래스에서 상황에 맞게 변경해야하는 경우 오버라이딩할 필요가 생깁니다.
⭐️ 즉, 상위 클래스의 메서드를 하위 클래스가 재정의 하는 것 입니다.
오버라이딩의 조건
오버라이딩은 부모 클래스의 메소드를 재정의하는 것이므로, 자식 클래스에서는 오버라이딩하고자 하는 메소드의 이름, 매개변수(파라미터), 리턴 값이 모두 같아야 합니다.
메서드의 이름은 물론 매개변수(파라미터)의 갯수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용됩니다.
⭐️ 즉, 부모 클래스의 메소드를 오버라이딩하는 것은 내용만을 새로 정의하는 것이므로 선언부는 부모의 것과 완벽히 동일해야 하는 것을 볼 수 있습니다.
@Override는 어떤 용도인가?
이는 어노테이션(Annotation)이라는 것으로 직역하면 주석이라는 뜻입니다. 이는 일반적인 주석과 다르게, 검증하는 기능을 합니다. 여기서 사용된 @Override라는 어노테이션은 오버라이딩을 검증하는 기능을 합니다. 코드상으로 검사했을 때 오버라이딩이 실제로 시행되지 않았다면 컴파일시 오류를 출력해주는 역할입니다.
쉽게 예시를 들어보면 부모 클래스인 Car 클래스의 engine 메소드를 '붕붕'이라고 정의했지만 자식 클래스인 Suv 클래스와 Sedan 클래스를 만들면서 엔진 소리를 다르게 출력하고 싶어집니다. 그래서 Suv 클래스와 Sedan 클래스에서 부모인 Car 클래스의 engine 메소드의 이름만 빌려와서 본인들의 방식대로 정의하여 '드릉드릉', '부왕'이라고 바꿔 사용해주는 걸 오버라이딩이라 합니다.
오버라이딩에서 접근 제어자를 설정하는 규칙
1. 자식 클래스에서 오버라이딩하는 메소드의 접근 제어자는 부모 클래스보다 더 좁게 설정할 수 없다.
부모클래스의 접근제어자는 default로 설정되어 있다면 자식 클래스들은 default보다 같거나 더 넓은 범위의 접근제어자만 설정할 수 있으므로 default, protected, public 이 세 개의 접근 제어자는 사용이 가능하지만 private는 사용 불가능합니다.
2. 예외(Exception)는 부모 클래스의 메소드 보다 많이 선언할 수 없다.
부모 클래스에서 어떤 예외를 throws 한다고 하면, 자식 클래스에서는 그 예외보다 더 큰 범위의 예외를 throws할 수 없습니다.
3. static 메소드를 인스턴스의 메소드로 또는 그 반대로 바꿀 수 없다.
부모 클래스의 static 메소드를 자식에서 같은 이름으로 정의할 수 있지만 이것은 다시 정의하는 것이 아니라 같은 이름의 static메소드를 새로 정의하는 것입니다.
오버로딩 vs 오버라이딩
이 둘은 이름만 비슷하지 사실 명백히 다릅니다.
오버로딩 - 기존에 없는 새로운 메소드를 추가하는 것
오버라이딩 - 상속받은 메소드를 재정의 하는 것
구분 | Overriding | Overloading |
접근 제어자 | 부모 클래스의 메소드의 접근 제어자보다 더 넓은 범위의 접근 제어자만 자식 클래스의 메소드에서 설정할 수 있음 | 모든 접근 제어자를 사용할 수 있음 |
리턴형 | 동일해야 함 | 달라야만 함 (반드시 매개 변수도 달라야함) |
메소드명 | 동일해야 함 | 동일해야 함 |
매개 변수 | 동일해야 함 | 달라야만 함 |
적용 범위 | 상속관계에서 적용 | 같은 클래스 내에서 적용 |