[java] Java에서 상속을 금지해야하는 좋은 이유는 무엇입니까?

Java에서 상속을 금지해야하는 이유는 무엇입니까 (예 : 단일 개인용 매개 변수없는 생성자를 사용하는 최종 클래스 또는 클래스 사용)? 방법을 최종적으로 만드는 좋은 이유는 무엇입니까?



답변

여기에서 가장 잘 언급 할 것은 Joshua Bloch의 훌륭한 책 “Effective Java”의 항목 19이며, “상속을위한 디자인 및 문서 또는 금지”입니다. (제 2 판의 17 번 항목과 제 1 판의 15 번 항목입니다.) 실제로 읽어야하지만 요약하겠습니다.

상속 된 클래스와 부모와의 상호 작용은 조상이 상속되도록 설계되지 않은 경우 놀랍고 실행 불가능합니다.

그러므로 수업은 두 종류로 이루어져야합니다.

  1. 확장 되도록 고안된 클래스 및 수행 방법을 설명하기위한 충분한 문서

  2. 최종으로 표시된 수업

순전히 내부 코드를 작성하는 경우 약간 과잉 일 수 있습니다. 그러나 클래스 파일에 5자를 추가하는 데 드는 추가 노력은 매우 적습니다. 내부 소비에 대해서만 작성하는 경우 미래 ​​코더는 항상 ‘최종’을 제거 할 수 있습니다. “이 클래스는 상속을 염두에두고 설계되지 않았다”는 경고로 생각할 수 있습니다.


답변

클래스를 재정의하면 다른 메서드에서 계산되는 동작을 변경할 수 없도록 메서드를 최종적으로 만들 수 있습니다. 생성자에서 호출 된 메소드는 종종 final로 선언되므로 객체를 만들 때 불쾌한 놀라움을 느끼지 않습니다.


답변

클래스를 마지막으로 만드는 한 가지 이유는 상속보다 구성을 강요하려는 경우입니다. 이것은 일반적으로 클래스 간의 긴밀한 연결을 피하는 데 바람직합니다.


답변

최종 방법으로 갈 수있는 3 가지 사용 사례가 있습니다.

  1. 파생 클래스가 특정 기본 클래스 기능을 재정의하지 않도록합니다.
  2. 이것은 기본 클래스가 파생 클래스가 변경하지 않아야하는 프레임 워크의 중요한 핵심 기능을 제공하는 보안 목적입니다.
  3. 최종 및 개인 메소드에 가상 테이블 개념을 사용하지 않으므로 최종 메소드는 인스턴스 메소드보다 빠릅니다. 따라서 가능한 경우에는 최종 방법을 사용하십시오.

수업을 마무리하기위한 목적 :

어떤 신체도 그러한 클래스를 확장하고 그들의 행동을 바꿀 수 없습니다.

예 : 래퍼 클래스 정수는 최종 클래스입니다. 해당 클래스가 최종 클래스가 아닌 경우 어느 누구도 Integer를 자신의 클래스로 확장하고 정수 클래스의 기본 동작을 변경할 수 있습니다. 이를 피하기 위해 java는 모든 래퍼 클래스를 최종 클래스로 만들었습니다.


답변

불변의 객체 ( http://en.wikipedia.org/wiki/Immutable_object )를 만들거나 싱글 톤 ( http://en.wikipedia.org/wiki/Singleton_pattern ) 을 만들 거나 원하는 경우 효율성, 안전 또는 보안상의 이유로 누군가가 메소드를 대체하지 못하도록합니다.


답변

상속은 전기 톱과 같습니다-매우 강력하지만 잘못된 손에는 끔찍합니다. 상속 할 클래스를 설계하거나 (유연성을 제한하고 더 오래 걸릴 수 있음) 금지해야합니다.

Effective Java 2nd edition items 16 and 17 또는 내 블로그 게시물 “Inheritance Tax”를 참조하십시오 .


답변

흠 … 두 가지를 생각할 수 있습니다.

특정 보안 문제를 다루는 클래스가있을 수 있습니다. 공격자는이를 하위 분류하고 시스템의 하위 분류 버전을 시스템에 공급함으로써 보안 제한을 우회 할 수 있습니다. 예를 들어 응용 프로그램에서 플러그인을 지원할 수 있으며, 플러그인이 보안 관련 클래스를 서브 클래 싱 할 수있는 경우이 트릭을 사용하여 서브 클래스 버전의 플러그인을 제자리에 밀입시킬 수 있습니다. 그러나 이것은 애플릿 등과 관련하여 Sun이 처리해야하는 문제 일 수 있습니다.

훨씬 더 현실적인 것은 객체가 변경 가능한 것을 피하는 것입니다. 예를 들어 문자열은 변경할 수 없으므로 코드에서 안전하게 참조를 유지할 수 있습니다

 String blah = someOtherString;

먼저 문자열을 복사하는 대신. 그러나 문자열을 서브 클래 싱 할 수있는 경우 문자열 값을 수정할 수있는 메소드를 추가 할 수 있습니다. 이제는 위와 같이 문자열을 복사하면 문자열이 동일하게 유지되는 코드를 더 이상 신뢰할 수 없습니다. 끈.