문제

왜 누군가가 수업을 최종 또는 봉인으로 표시하고 싶은가?

도움이 되었습니까?

해결책

에 따르면 위키 백과, "밀봉 된 클래스는 주로 파생을 방지하는 데 사용됩니다. 컴파일 시간 동안 또 다른 수준의 엄격함을 추가하고 메모리 사용량을 개선하며 런타임 효율성을 향상시키는 특정 최적화를 유발합니다."

또한 Patrick Smacchia의 블로그:

  • 버전 작성 : 클래스가 원래 봉인되면 호환성을 깨뜨리지 않고 미래에 알려지지 않은 것으로 변경 될 수 있습니다. (…)

  • 성능 : (…) JIT 컴파일러가 밀봉 된 유형을 사용하여 가상 메소드에 대한 호출을 보면 JIT 컴파일러는 메소드를 비정규 적으로 호출하여보다 효율적인 코드를 생성 할 수 있습니다. (…)

  • 보안 및 예측 가능성 : 클래스는 자체 상태를 보호해야하며 스스로 손상되지 않아야합니다. 클래스가 풀리지 않으면 파생 클래스는 내부적으로 필드를 조작하는 데이터 필드 또는 방법이 개인이 아닌 개인이 아닌 경우 기본 클래스의 상태에 액세스하고 조작 할 수 있습니다. (…)

그것들은 모두 꽤 좋은 이유입니다 - 나는 실제로 지금 그것을 찾을 때까지 성능 혜택의 영향을 알지 못했습니다 :)

버전 및 보안 포인트는 코드 신뢰도 측면에서 큰 이점처럼 보이며, 이는 모든 종류의 큰 프로젝트에서 매우 정당화됩니다. 물론 단위 테스트에는 드롭 인이 아니지만 도움이 될 것입니다.

다른 팁

상속 유형을 만드는 것은 대부분의 사람들이 생각하는 것보다 훨씬 어려운 일이기 때문입니다. 표시하는 것이 가장 좋습니다 모두 이 방법으로 기본적으로 유형은 다른 사람들이 확장되지 않은 유형에서 다른 사람들이 물려받지 못하게합니다.

유형이 확장되어야하는지 여부는 나중에 와서 확장하려는 개발자가 아닌 개발자의 결정입니다.

조슈아 블로 치 (Joshua Bloch)는 그의 저서의 효과적인 자바가 그것에 대해 이야기합니다. 그는 "상속을 위해 문서화하거나 허용하지 않는다"고 말합니다. 요점은 클래스가 저자와 고객 간의 계약이라는 것입니다. 클라이언트가 기본 클래스에서 상속받을 수있게되면이 계약이 훨씬 엄격 해집니다. 당신이 그것으로부터 상속 될 경우, 당신은 아마도 몇 가지 방법을 무시할 것입니다. 그렇지 않으면 상속을 구성으로 대체 할 수 있습니다. 어떤 메소드를 재정의 할 수 있고, 구현 해야하는 방법은 문서화되어야합니다. 그렇지 않으면 코드가 예측할 수없는 결과로 이어질 수 있습니다. 내가 기억하는 한, 그는 그러한 예를 보여줍니다 - 여기에 방법이있는 컬렉션 클래스가 있습니다.

public interface Collection<E> extends Iterable<E> {    
  ...
  boolean add(E e);
  boolean addAll(Collection<? extends E> c);
  ...
}

일부 구현, 즉 Arraylist가 있습니다. 이제 당신은 그것에서 상속하고 일부 방법을 무시하려고하므로 요소가 추가 될 때 메시지를 콘인트로 인쇄합니다. 이제 두 가지를 무시해야합니까? 추가하다 그리고 addall, 또는 전용 추가하다? 그것은 방법에 달려 있습니다 addall 구현됩니다 - 내부 상태에서 직접 작동합니까 (Arraylist와 같이) 또는 호출 추가하다 (AbstractCollection과 같이). 또는있을 수 있습니다 추가 된 내부, 둘 다에 의해 호출됩니다 추가하다 그리고 addall. 이 수업에서 상속하기로 결정할 때까지 그러한 질문은 없었습니다. 당신이 그것을 사용한다면 - 그것은 당신을 괴롭히지 않습니다. 그래서 수업의 저자는 당신이 그의 수업에서 물려 받기를 원한다면 그것을 문서화해야합니다.

그리고 그가 미래에 구현을 바꾸고 싶다면 어떨까요? 그의 수업이 사용되는 경우, 결코 상속받지 않으면 아무것도 구현을 더 효율적으로 변경하는 것을 막을 수 없습니다. 이제 그 수업에서 상속된다면 소스를보고 addall 전화 추가하다, 당신은 반복됩니다 추가하다. 나중에 저자는 구현을 변경합니다 addall 더 이상 전화가 아닙니다 추가하다 - 프로그램이 깨졌고 메시지가 인쇄되지 않습니다. addall 호출됩니다. 또는 당신은 소스를보고 그것을 발견했습니다 addall Add를 호출하지 않으므로 재정의합니다 추가하다 그리고 addall. 이제 저자는 구현을 변경합니다 addall 전화 추가하다 - 프로그램이 다시 깨졌습니다 addall 메시지는 각 요소에 대해 두 번 인쇄됩니다.

따라서 - 수업을 상속 받기를 원한다면 방법을 문서화해야합니다. 미래에 일부 서브 클래스를 깨뜨릴 수있는 무언가를 바꿔야한다고 생각되면 피하는 방법을 생각해야합니다. 고객이 클래스에서 상속받을 수있게함으로써 클래스를 사용할 때 할 때 수행하는 훨씬 더 많은 내부 구현 세부 정보를 노출시킵니다. 내부 워크 플로우를 노출시켜 종종 향후 버전의 변경이 적용됩니다.

세부 사항을 노출시키고 고객이 그들에게 의존하면 더 이상 변경할 수 없습니다. 그것이 당신에게 괜찮거나, 당신이 할 수있는 것과 재정의 할 수없는 것을 문서화했다면 - 괜찮습니다. 때때로 당신은 그것을 원하지 않습니다. 때때로 당신은 단지 "내부 구현 세부 정보를 자유롭게 변경할 수 있기 때문에이 클래스를 사용하고 상속받지 마십시오"라고 말하고 싶어합니다.

따라서 기본적으로 "수업은 자녀를 갖고 싶지 않기 때문에 우리는 그것이 소원을 존중해야하기 때문에"댓글을 달아야합니다.

따라서 누군가가 가능한 구현 세부 사항 변경이 상속보다 가치가 있다고 생각할 때 클래스를 최종/봉인으로 표시하려고합니다. 상속과 유사한 결과를 달성하는 다른 방법이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top