2010-05-14 4 views
6

자바에서는 구체적인 메소드와 추상 메소드가 모두 포함 된 추상 클래스를 정의하며, 제 3 자 개발자가 독립적으로 서브 클래 싱해야합니다. 확실한 것은 : 클래스와 소스가 호환되지만 바이너리와 호환되지 않는 추상적 인 클래스를 만들 수있는 변경이 있습니까? 즉, 하위 클래스를 컴파일 한 후에는 추상 클래스를 변경할 수 있습니까? 그것에 추상적 인 메소드를 추가하거나 하위 클래스에 의해 호출되는 protected 메소드를 제거합니다. 물론 소스와 호환되지 않습니다 - 서브 클래스를 다시 컴파일하도록 강제 할 수 있습니까?자바 - 추상 클래스와 서브 클래스의 이진 호환성

답변

8

직렬화 클래스에 필드를 추가 할 수 있습니다, 당신이 그렇게 할 것을 제안했다. 오버라이드는 일반적으로 기능을 사용자 정의하는 좋은 방법이 아닙니다. 매우 취약하기 때문입니다. 예를 들어 나중에 클라이언트가 사용했던 메소드 이름 (나중에 자동으로 무효화 됨)을 사용하면 재정의가 클래스의 invariant를 완전히 깨뜨릴 수 있습니다. 일반적으로 맞춤 설정을 제공하는 더 좋은 방법은 고객에게 맞춤 설정된 비헤이비어로 제한된 인터페이스를 제공 한 다음이 인터페이스의 인스턴스에 의존하는 완전한 구체적인 클래스를 가지며 필요한 경우 인터페이스에 적절하게 위임하는 것입니다. 사용자 정의 된 비헤이비어를 사용하십시오. 이렇게하면 코드와 클라이언트의 코드가 완전히 분리되어 서로 간섭하지 않게됩니다.

+0

대안을 제공해 주셔서 감사합니다.그것은 또한 내가 고려한 것입니다. (구현에 대한 참조를 유지하고 그것에 위임하는) 복잡성으로 인해 비용이 많이 들었습니다.하지만이 플러 거블 아키텍처가 필요하기 때문에이를 수행 할 것입니다. – thSoft

2

확실히.

갑자기 오버라이드 된 사용 된 메소드 이름을 우연히 사용하여 결과가 크게 다를 수 있습니다.

당신은이 시스템을 변경 너무 늦게하지 않으면 엉망 등

5

기술적 인면에서 "바이너리 비 호환성"을 사용한다고 가정합니다. 예 : 여기서 클래스 로더는 비 호환성을 감지하고 클래스를로드하는 것을 거부합니다. 당신이 볼 방법 을 추가이 그것을 final를 선언하고, 그 방법은 타사 서브 클래스의 일부 기존 방법의 서명이 충돌하는 경우

바이너리 호환성도 도입 할 수있다. 그러나 메서드가 final이 아닌 경우 기존 메서드는 문제를 일으킬 수있는 (새) 메서드의 재정의로 바뀌지 만 바이너리 비 호환성은 아닙니다.

마찬가지로 새로운 표시 필드를 추가하면 숨기기가 발생하고 혼동을 줄 수 있으며 객체 직렬화가 중단됩니다. 그러나 이것이 바이너리 비 호환성을 초래하지는 않습니다.

일반적으로 이것은 응용 프로그램 의미 문제와 간단한 이진 호환성을 고려해야한다는 사실을 나타냅니다. 자바 타입 시스템은 당신을 도울 수 없습니다.

  • 이 추상 클래스 및/또는 그 방법의 가시성을 감소
  • : 완성도를 들어

    , 제 3 자 클래스에 대한 바이너리 호환성을 끊을 코드에서 할 수있는 다른 일이있다 매개 변수 결과 및 예외 유형으로 사용되는 다른 클래스의

  • 변화를 서명,
  • 변경하여 추상 클래스는 확장 상위 클래스의 사슬, 또는 해당 클래스에서 호환되지 않는 변경, 또는
  • 변화 인터페이스 t의 나무 모자가 abstract 클래스를 구현하고 있지 않는 경우, 또는 그러한 인터페이스로 호환성이없는 변경을 실시했을 경우
+0

포괄적 인 답변을 주셔서 감사 드리며 내가 생각한 바를 생각해 보았지만 구현 자의 코드를 위반하는 다른 방법을 생각해보십시오. – thSoft

+0

좋은 답변입니다. 바이너리 및 소스 호환성에 대한 규칙은 서로 매우 독립적입니다. 둘을 따로 이해하는 것이 중요합니다. http://motlin.com/2010/binary-and-source-backwards-compatibility/ –

관련 문제