Java의 상속을 금지 해야하는 좋은 이유?
-
03-07-2019 - |
문제
예를 들어 단일 개인 매개 변수가없는 생성자를 사용하여 최종 클래스 또는 클래스를 사용하여 Java의 상속을 금지하는 데 필요한 이유는 무엇입니까? 방법을 최종적으로 만드는 데 좋은 이유는 무엇입니까?
해결책
여기서 가장 좋은 참조는 Joshua Bloch의 훌륭한 책 "Effective Java"의 항목 19, "상속을위한 디자인 및 문서 또는 그렇지 않으면 금지합니다." (이것은 제 2 판의 항목 17이고 첫 번째 판의 항목 15입니다.) 실제로 읽어야하지만 요약하겠습니다.
상속 수업과 부모와의 상호 작용은 조상이 상속되지 않도록 설계되지 않았다면 놀랍고 예측할 수 없습니다.
그러므로 수업은 두 가지 종류로 나와야합니다.
클래스 설계되었습니다 펼친, 그리고 그것이 어떻게 해야하는지 설명하기에 충분한 문서로
클래스 두드러진 결정적인
순수한 내부 코드를 작성하는 경우 약간 과잉 일 수 있습니다. 그러나 클래스 파일에 5자를 추가하는 데 관련된 추가 노력은 매우 작습니다. 내부 comsumption을 위해서만 글을 쓰고 있다면 미래의 코더는 항상 '최종'을 제거 할 수 있습니다. "이 클래스는 상속을 염두에두고 설계되지 않았다"는 경고로 생각할 수 있습니다.
다른 팁
재정의 클래스가 다른 방법에서 계산되는 동작을 변경할 수 없도록 메소드를 최종 최종으로 만들 수 있습니다. 생성자에 불리는 방법은 종종 최종적으로 선언되므로 객체를 만들 때 불쾌한 놀라움을 얻지 못합니다.
수업을 결승하게 만드는 한 가지 이유는 당신이 상속을 통해 구성을 강요하고 싶을 때 때문입니다. 이것은 일반적으로 클래스 간의 단단한 커플 링을 피하는 데 바람직합니다.
최종 방법으로 갈 수있는 3 가지 사용 사례가 있습니다.
- 파생 클래스가 특정 기본 클래스 기능을 재정의하는 것을 피하기 위해.
- 이것은 기본 클래스가 파생 클래스를 변경하지 않아야하는 프레임 워크의 중요한 핵심 기능을 제공하는 보안 목적입니다.
- 최종 및 개인 방법에 가상 테이블 개념을 사용하지 않기 때문에 최종 방법은 인스턴스 방법보다 빠릅니다. 따라서 가능성이있는 곳이라면 최종 방법을 사용하십시오.
수업을 최종적으로 만들기위한 목적 :
어떤 몸도 그 수업을 연장하고 행동을 바꿀 수 없도록합니다.
예 : 래퍼 클래스 정수는 최종 클래스입니다. 해당 수업이 최종적이지 않으면 정수를 자신의 클래스로 확장하고 정수 클래스의 기본 동작을 변경할 수 있습니다. 이를 피하기 위해 Java는 모든 래퍼 클래스를 최종 클래스로 만들었습니다.
불변의 물건을 만들고 싶을 수도 있습니다 (http://en.wikipedia.org/wiki/immutable_object), 싱글 톤을 만들고 싶을 수도 있습니다 (http://en.wikipedia.org/wiki/singleton_pattern) 또는 효율성, 안전 또는 보안의 이유로 누군가가 방법을 무시하는 것을 방지 할 수도 있습니다.
상속은 전기 톱과 같습니다. 매우 강력하지만 잘못된 손에는 끔찍합니다. 유연성을 제한하고 더 오래 걸릴 수있는 클래스를 디자인하거나 금지해야합니다.
효과적인 Java 2nd Edition Items 16 및 17 참조 또는 내 블로그 게시물 참조 "상속세".
흠 ... 두 가지를 생각할 수 있습니다.
특정 보안 문제를 다루는 클래스가있을 수 있습니다. 이를 서브 클래싱하고 시스템에 공급하여 서브 클래스 버전을 공급함으로써 공격자는 보안 제한을 우회 할 수 있습니다. 예를 들어 애플리케이션은 플러그인을 지원할 수 있으며 플러그인이 보안 관련 클래스를 서브 클래스 할 수있는 경우이 트릭을 사용하여 서브 클래스 버전을 제자리에 밀수 할 수 있습니다. 그러나 이것은 오히려 태양이 애플릿 등과 관련하여 다루어야 할 것입니다.
훨씬 더 현실적인 것은 물체가 변하는 것을 피하는 것입니다. 예 : 문자열은 불변이기 때문에 코드는 안전하게 참조를 유지할 수 있습니다.
String blah = someOtherString;
먼저 문자열을 복사하는 대신. 그러나 문자열 서브 클래스를 할 수 있다면 문자열 값을 수정할 수있는 메소드를 추가 할 수 있습니다. 이제 코드는 위와 같이 문자열을 복사하는 경우 문자열이 동일하게 유지되는 것을 더 이상 의존 할 수 없습니다. 끈.
사람들이 자신과 다른 사람들을 혼동 할 수있는 일을하는 것을 막기 위해. 정의 된 상수 또는 계산이있는 물리 도서관을 상상해보십시오. 최종 키워드를 사용하지 않으면 누군가가 와서 절대 변하지 말아야 할 기본 계산 또는 상수를 재정의 할 수 있습니다.
또한 상업용 폐쇄 소스 클래스를 작성하는 경우 사람들이 기능을 변경할 수 있기를 원하지 않을 수도 있습니다. 특히 사람들이 귀하의 방법을 지원해야하고 사람들이 귀하의 방법을 무시하고 전화를 걸었다 고 불평하는 경우 예상치 못한 결과.
클래스와 메소드를 최종적으로 표시하면 런타임이 주어진 객체에 대해 올바른 클래스 메소드를 찾을 필요가 없기 때문에 작은 성능 게인이 표시 될 수 있습니다. 비 결절 방법은 가상으로 표시되므로 필요한 경우 올바르게 확장 할 수 있도록 최종 방법을 직접 연결하거나 클래스에서 컴파일 할 수 있습니다.
재정의 클래스가 동작을 바꾸지 않도록 메소드를 최종적으로 만들고자합니다. 행동을 바꿀 수 있기를 원할 때 방법을 공개하십시오. 공개 방법을 무시하면 변경할 수 있습니다.