오버라이딩(Overriding)
조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버 라이딩이라고 한다.
class Point{
int x;
int y;
String getLocation() {
return "x :" + x + ", y : " + y;
}
}
class Point3D extends Point {
int z;
@Overriding
String getLocatuin() { // 오버라이딩
return "x :" + x + ", y :" + y + ", z :" +z;
}
}
이 두 클래스는 서로 상속관계에 있으므로 Point 3D클래스는 Point클래스로부터 getLocation()을 상속 받지만, Point3D클래스는 3차원 좌표계의 한 점을 표현하기 위한 것이므로 조상인 Point클래스로부터 상속받은 getLocation()은 Point 3D클래스에 맞지 않는다. 그래서 이 메서드를 Point3D클래스 자신에 맞게 z축의 좌표값도 포함하여 반환하도록 오버라이딩 하였다.
오버라이딩 조건
오버라이딩은 메서드의 내용만을 새로 작성하는 것이므로 메서드의 선언부(메서드 이름, 매개변수, 반환 타입)는 조상의 것과 완전히 일치해야 한다. 다만 접근 제어자(access modifier)와 예외(exception)는 제한된 조건 하에서만 다르게 변경할 수 있다.
- 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- 만일 조상 클래스에 정의된 메서드의 접근 제어자가 protected라면, 이를 오버라이딩하는 자손 클래스의 메서드는 접근 제어자가 protected나 public이어야 한다. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 있다.
- 아래의 코드를 보면 Child클래스의 parentMethod()에 선언된 예외의 개수가 조상인 Parent클래스의 parentMethod()에 선언된 예외의 개수보다 적으므로 바르게 오버라이딩 되었다.
조상 클래스의 메서드를 자손 클래스에서 오버라이딩 할 때
- 선언부가 조상 클래스의 메서드와 일치해야 한다.
- 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
오버로딩(Overloading)
한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의할 수 있다.
오버로딩의 조건
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 반환 타입은 상관없다.
위의 조건을 만족시키지 못하는 메서드는 중복 정의로 간주되어 컴파일 시에 에러가 발생한다.
오버로딩된 메서드들은 매개변수에 의해서만 구별될 수 있으므로 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
오버로딩의 예
println()
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)
매개변수의 이름이 다르고 매개변수의 타입이 같은 경우
int add(int a, int b) { return a+b;}
int add(int x, int y) { return x+y;}
위의 두 메서드는 매개변수의 이름만 다를 뿐 매개변수의 타입이 같기 때문에 오버로딩이 성립하지 않는다.
컴파일하면, ‘add(int, int) is already defined(이미 같은 메서드가 정의되었다.)’라는 메시지가 나타날 것이다.
리턴 타입만 다른 경우
int add(int a, int b) { return a+b; }
long add(int a, int b) { return (long)(a+b); }
이번 경우는 리턴 타입만 다른 경우이다. 매개변수의 타입과 개수가 일치하기 때문에 add(3,3)과 같이 호출하였을 때 어떤 메서드가 호출된 것인지 결정할 수 없기 때문에 오버로딩으로 간주하지 않는다.
매개변수의 순서가 다른 경우
long add(int a, long b) {return a+b;}
long add(long a, int b) { return a+b;}
두 메서드 모두 int형과 long형 매개변수가 하나씩 선언되어 있지만, 서로 순서가 다른 경우이다. 이 경우에는 호출 시 매개변수의 값에 의해 호출될 메서드가 구분될 수 있으므로 중복된 메서드 정의가 아닌, 오버 로딩으로 간주한다.
단지 매개변수의 순서만을 다르게 하여 오버로딩을 구현하면, 사용자가 매개변수의 순서를 외우지 않아도 되는 장점이 있지만, 오히려 단점이 될 수도 있기 때문에 주의해야 한다.
오버로딩 vs 오버라이딩
오버로딩은 기존에 없는 새로운 메서드를 추가하는 것이고, 오버라이딩은 조상으로부터 상속받은 메서드의 내용을 변경하는 것이다.
오버로딩(overloading) 기존에 없는 새로운 메서드를 정의하는 것(new)
오버라이딩(overriding) 상속받은 메서드의 내용을 변경하는 것(change, modify)
class Parent {
void parentMethod(){}
}
class Child extends Parent {
void parentMethod() {} // 오버라이딩
void parentMethod(int i) {} // 오버로딩
void childmethod() {}
void childMethod(int i) {} // 오버로딩
void childMethod(){} // 에러. 중복정의 되었음(already defined in Child)
}
'Server > Java' 카테고리의 다른 글
[JDBC] JDBC의 이해 (0) | 2022.11.02 |
---|---|
[Jdbc] queryForObject와 Update의 차이점, queryForObject 변경사항 (0) | 2022.11.02 |
[Java] JDK, JRE (0) | 2022.09.21 |
[Java] JDK 환경변수 설정 이유 (0) | 2022.09.20 |
[Java] OpenJDK 11 설치 (0) | 2022.09.19 |