프로그래밍 언어/Java

Java(오버라이딩(overriding))

benjykim 2017. 8. 17. 18:33
반응형

*이 포스트는 남궁성님의 '자바의 정석'책을 참고하여 작성했습니다.


* 오버라이딩

: 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다. 

상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스 자신에 맞게 변경해야하는 경우가 많다. 

이럴 때 조상의 메서드를 오버라이딩한다.


 - 예제

: 2차원 좌표계의 한 점을 표현하기 위한 Point클래스가 있을 때, 이를 조상으로 하는 Point3D클래스, 

3차원 좌표계의 한 점을 표현하기 위한 클래스를 다음과 같이 새로 작성하였다고 하자.


class Point {

int x;

int y;


String getLocation() {

return "x : "+ x + ", y : " +y;

}

}

class Point3D extends Point {

int z;


String getLocation() {                                //오버라이딩

return "x :" + x + ",y : " + y + ",z : " + z;

}

}


-> Point 클래스의 getLocation()은 한 점의 x,y 좌표를 문자열로 반환하도록 작성되었다. 

이 두 클래스는 서로 상속관계에 있으므로 Point3D클래스는 Point클래스로부터 getLocation()을 상속받지만, 

Point3D 클래스는 3차원 좌표계의 한 점을 표현하기 위한 것이므로 조상인 Point 클래스로부터 상속받은 

getLocation()은 Point3D클래스에 맞지 않는다. 

그래서 이 메서드를 Point3D클래스 자신에 맞게 z축의 좌표값도 포함하여 반환하도록 오버라이딩 하였다.





* 오버라이딩의 조건

: 자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와


 1) 이름이 같아야 한다.

 2) 매개변수가 같아야 한다.

 3) 반환타입이 같아야 한다.


-> 한마디로 요약하면 선언부가 서로 일치해야 한다. 다만 접근 제어자와 예외는 제한된 조건 하에서만 

다르게 변경될 수 있다.



* 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.

-> 만일 조상 클래스에 정의된 메서드의 접근 제어자가 protected라면, 

이를 오버라이딩하는 자손 클래스의 메서드는 접근 제어자가 protected나 public이어야 한다. 

대부분의 경우 같은 범위의 접근 제어자를 사용한다. 




* 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.


 - 예제

class Parent {

void compliment() throws IOException, SQLException {

//..

}

}

class Child extends Parent {

void compliment() throws IOException {

//..

}

//..

}


-> 위의 코드를 보면 Child 클래스의 compliment()에 선언된 예외의 개수가 조상인 Parent 클래스의 

compliment()에 선언된 예외의 개수보다 적으므로 바르게 오버라이딩 되었다.


여기서 주의해야할 점단순히 선언된 예외의 개수의 문제가 아니라는 것이다.


class Child extends Parent {

void compliment() throws Exception {

//..

}

//..

}


-> 만일 위와 같이 오버라이딩 했다면, 분명히 조상클래스에 정의된 메서드보다 적은 개수의 예외를 선언한 것처럼 

보이지만 Exception은 모든 예외의 최고 조상이므로 가장 많은 개수의 예외를 던질 수 있도록 선언한 것이다. 

그래서 예외의 개수는 적거나 같아야 한다는 조건을 만족시키지 못하는 잘못된 오버라이딩인 것이다.



* 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없다.




Q. 조상 클래스에 정의된 static메서드를 자손 클래스에서 똑같은 이름의 

static메서드로 정의할 수 있나?


A. 가능하다. 하지만, 이것은 각 클래스에 별개의 static메서드를 정의한 것일 뿐 오버라이딩이 아니다. 

각 메서드는 클래스이름으로 구별될 수 있으며, 호출할 때는 '참조변수.메서드이름()'대신 '클래스이름.메서드이름()'으로 하는 것이 바람직하다. 즉, static멤버들은 자신들이 정의된 클래스에 묶여있다고 생각하면 된다!



반응형