[JAVA] 오버로딩 vs 오버라이딩

DongGyu Jung·2022년 1월 18일
0

자바(JAVA)

목록 보기
10/60
post-thumbnail

오버로딩과 오버라이딩..
얼핏보면 비슷해보이는데 둘이 뭐가 다른걸까??
철자가 다르긴 한데

우선 하나씩 알아가보도록 하자.


📌 오버로딩(overloading)

" 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것 "
▶ 마치 하나 이상(over)의 동일명 메서드가 있더라도 사용/컴파일(loading)할 수 있다는 것

메서드는 변수와 마찬가지로
" 같은 클래스 내에서 서로 구별될 수 있어야 한다. "

그렇기 때문에
각자 다른 이름을 가져야하는데

자바에서는
한 클래스 내에
" 이미 사용하려는 이름과 동일한 이름의 메서드가 있더라도 "
매개변수개수 / 타입이 다르다면
같은 이름을 사용해서 정의할 수 있다.

즉 같은 이름을 가진 메서드이더라도
매개변수를 근거로 분류하는 것이다.
( 그래서 변환 타입은 관계가 없는 것이다. )

※ 조건

  • 메서드 이름 동일
  • 매개변수의 개수 또는 타입달라야함
    ( 둘 중 하나만 달라도 된다. 게다가 유무有無로도 오버로딩 가능)
  • 변환 타입은 관계 없음.

예를 들면 println메서드가 있는데
우리가 실제로 해당 메서드를 어떠한 값이든 지정해주면 출력되었다.
아무런 문제가 발생하지 않았던 이유가

// PrintStream 클래스
void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(Object x)
void println(String x)

위와 같이
모든 종류의 타입.
어떤 종류의 매개변수를 지정해도 출력이 될 수 있도록
오버로딩 된 println메서드를 정의해 놓았기 때문이다.

그래서 이 메서드를 호출할 때
매개변수로 넘겨주는 값 타입에 따라 위 메서드들 중
동일한 값 타입 메서드가 선택되어 실행되는 것이다.

앞서 정리한 조건과 관련하여
오버로딩으로 간주하는 경우와 아닌 경우를
예시를 통해 살펴보자면

// ※ 오버로딩 X 
/* 
- 차이 = 매개변수 "이름"
- 개수 & 타입 : "동일"
*/
int add(int a, int b) { return a + b; }
int add(int x, int y) { return x + y; }

/* 
- 차이 = "반환(return) 타입 & 이름"
- 개수 & 타입 : "동일"
*/
int add(int a, int b) { return a + b; }
long add(int x, int y) { return x + y; }



// ※ 오버로딩 O
/* 
- 차이 = "매개변수 타입" & return타입
- 개수 : "동일"
*/
int add(int a, int b) { return a + b; }
long add(long a, long b) { return a + b; }

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

📌 오버라이딩(overriding)

" 상위 클래스가 가지고 있는 메서드를 하위 클래스재정의해서 사용하는 것 "
▶ overriding : "덮어쓰다"의 의미로 하위 클래스에서 덮어쓰는 '재정의'해서 사용하는

위에서 [상위 클래스 / 하위 클래스]라고 구분 지었지만
가장 흔한 표현이고 다들 알 만한 구분은
부모 클래스 / 자식 클래스 인데

이 경우로 다시 설명해보자면

"부모클래스에서 정의한 메서드"를
자식 클래스상속받아
부모 클래스에 있던 메서드재정의해서 사용하는 것을 말한다.

class Point {
    int x ;
    int y ;
    
    String getLoc() {
        return "x : " + x + ", y : " + y ;
    }
}

// 위 Point 클래스를 상속받았을 때
class Point3D extends Point { // 상속관계
    // int x ; 부모클래스 멤버 그냥 사용 가능
    // int y ; 부모클래스 멤버 그냥 사용 가능
    int z ; // Point3D 클래스에서 선언
    
    // 부모클래스에서 이미 상속받았던 getLoc()메서드를 다시 재정의
    String getLoc() { // 오버라이딩(overriding)
        return "x : " + x + ", y : " + y + ", z : " + z;
    }
}

여기서 상속을 받아왔기 때문에
부모클래스에 있던 변수들은

" 자식 클래스 내에서 선언하지 않더라도 "
그대로 사용 가능하다

※ 오버라이딩 조건

메서드 내용만 새로 작성하는 것이기 때문에
메서드의 선언부(이름, 매개변수, 반환타입 )는 완전히 일치해야 한다.

❗ 단, 접근제어자(access modifier) & 예외(Exception) 의 경우는 "제한된 조건하"에서 다르게 변경할 수 있다.
1. 접근제어자는 " 조상 클래스의 메서드 "보다 좁은 범위변경할 수 없다.
2. " 조상 클래스 "보다 많은 예외 선언불가하다.



🔍 차이점

" 확장 " vs " 재정의 "

오버로딩은
이름이 같은거지
실행에 필요한 매개변수나 타입 등이 서로 다른
즉, 겉은 같고 속은 서로 다른 동명이인 허용하는 형태이고

오버라이딩은
" 부모님 가게를 물려받았지만
자식의 새로운 경영으로 새로운 메뉴를 판매하게 된 가게 "와
비슷한 형태라고 보면
이해가 쉽다.

구분오버로딩오버라이딩
메서드 이름동일동일
매개변수 & 타입다름동일
Return(반환값) 타입상관 X동일

0개의 댓글