이전 주제 보기 :: 다음 주제 보기 |
글쓴이 |
메시지 |
한재호
가입: 2005년 10월 27일 올린 글: 14
|
올려짐: 2005년11월24일 15:49 주제: Java의 method override 문제 (원래 해야할 사람이 쓴.. - -) |
|
|
코드: |
class Socket
{
public void Receive(int _data)
{
System.out.println("받은 데이터 처리");
OnReceive(_data);
}
protected void OnReceive(int _data)
{
System.out.println(_data + " 받았다.");
}
}
class MySocket extends Socket
{
protected void OnReceive(int _data)
{
System.out.println(_data * 10 + " 받았다.");
}
}
public class Tester
{
public static void main(String argv[])
{
Socket socket = new MySocket();
socket.Receive(10);
}
}
|
위를 실행한 결과는
코드: |
D:\Bin\JAVA\_Test>java Tester
받은 데이터 처리
100 받았다.
|
입니다.
저런 OnReceive() 같은 함수를 흔히 이벤트 핸들러라 부르고, 라이브러리의 제작자는 사용하는 유저가 On.. () 씨리즈의 함수를 상속받아 원하는 행동을 하기를 바라고 작성하는 것입니다. 실제로 많은 라이브러리가 그렇게 제공되고 있고 자바에서 다중상속 대신 지원하는 interface 개념은 저런 것이 되지 않는다면 무용지물이 됩니다.
만약에 Socket 클래스 제작자가, 유저가 자신의 내부 함수를 오버라이드하여 원하지 않는 결과를 초래하는 것을 막고 싶다면 자바에선 다음의 두 가지 방법이 있습니다.
1) private void OnReceive() ...
이렇게 되면 상속받은 MySocket 클래스에선 아예 Socket의 OnReceive()함수의 존재조차 모르게 되고 설사 MySocket에 OnReceive() 함수를 재정의 한다고 해도 이름만 같을 뿐이지 override 함수가 아닌 것이 됩니다.
2) protected final OnReceive()...
함수의 정의에 final 키워드를 붙이면 하위 클래스에서 오버라이드를 할 수 없게 컴파일러가 막아줍니다. 이렇게 하면 1)번과 달라지는 것은 1)에선 MySocket에서 Socket의 OnReceive() 함수를 호출할 수 없었지만(private이므로) 이 경우엔 호출하여 사용할 수 있습니다. 다만 재정의할 수 없을 뿐이죠.
이 외에 자바에선 지원하지 않지만 C++에선
virtual 함수의 call 방법을 static call로 강제하는 방법이 있습니다.
예를 들면 이렇게요.
코드: |
void Socket::Receive(int _data)
{
printf("받은 데이터 처리");
Socket::OnReceive(_data); // 여기
}
|
이렇게 하면 '여기' 부분이 컴파일될때 virtual function table에서 함수의 주소를 찾아서 call하는 코드가 들어가는 것이 아니라. static하게 Socket::OnReceive()함수로 연결됩니다. 따라서 아무리 상속을 받아서 OnReceive() 함수를 재정의 해도 소용이 없게 됩니다.
여기까지입니다 |
|
위로 |
|
|
이광근
가입: 2005년 8월 29일 올린 글: 68
|
올려짐: 2005년11월25일 10:55 주제: |
|
|
명심하길빈다
위험한도구다
양날의칼이다
손비지않도록
조심해주기를
안전장치들을
잊지말고쓰길
-K |
|
위로 |
|
|
한재호
가입: 2005년 10월 27일 올린 글: 14
|
올려짐: 2005년11월25일 14:59 주제: |
|
|
명심하겠습니다 m(__)m |
|
위로 |
|
|
|