문제

Java에서는 비 청구 클래스를 확장 할 수있는 사례가 있습니까?

클래스 계층이있을 때 항상 나쁜 코드를 나타내는 것 같습니다. 당신은 동의하고 왜/ 왜 그렇지 않습니까?

도움이 되었습니까?

해결책

나는 Jon과 Kent에 동의하지만 Scott Myers (효과적인 C ++)처럼 훨씬 더 나아갑니다. 나는 그것을 믿는다 모든 수업도 마찬가지입니다 abstract, 또는 final. 즉, 계층 구조의 잎 클래스 만 직접적인 인스턴스화에 적합합니다. 다른 모든 클래스 (즉, 상속의 내부 노드)는 "미완성"이므로 결과적으로 abstract.

일반적인 클래스가 더 확장되는 것은 의미가 없습니다. 클래스의 측면이 확장 및/또는 수정할 가치가있는 경우 더 깨끗한 방법은 해당 클래스를 가져 와서 하나로 분리하는 것입니다. abstract 기본 클래스 및 하나의 콘크리트 교체 가능한 구현.

다른 팁

비 결합 콘크리트 클래스를 갖는 것이 합리적 인 경우가 있습니다. 그러나 Kent에 동의합니다. 클래스는 기본적으로 최종 (C#로 봉인)해야하며 Java 메소드는 기본적으로 최종적이어야한다고 생각합니다 (C#에있는대로).

Kent가 말했듯이 상속은 신중한 설계 및 문서가 필요합니다. 단일 방법을 무시할 수 있다고 생각하기는 매우 쉽지만 나머지 구현의 일부로 기본 클래스에서 해당 방법을 호출 할 수있는 상황을 알지 못합니다.

보다 "상속 수업을 어떻게 설계합니까?" 이것에 대한 자세한 내용은.

이 질문은 C# .net과 같은 다른 플랫폼에도 적용됩니다. 유형이 기본적으로 최종/봉인되어야하며 상속을 허용하기 위해 명시 적으로 알려지지 않아야한다고 믿는 사람들이 있습니다.

상속을 통한 확장은 신중한 디자인이 필요한 것이며 유형을 확보하지 못하는 것만 큼 간단하지 않은 것입니다. 그러므로 나는 상속을 허용하는 것이 명백한 결정이라고 생각합니다.

코드를 비정규로 유지해야 할 좋은 이유가 있습니다. Hibernate, Spring, Guice와 같은 많은 프레임 워크는 때때로 런타임에 동적으로 확장되는 비 결합 클래스에 의존합니다.

예를 들어, 최대 절전 모드 게으른 연관 페치에 프록시를 사용합니다. 특히 AOP에 관해서는 인터셉터가 부착 될 수 있도록 수업을 비정치로 원할 것입니다. 참조 그렇게 질문

여기서 가장 좋은 참조는 Joshua Bloch의 훌륭한 책 "Effective Java"의 항목 15입니다. 그러나 클래스 확장이 허용되어야하는지 여부의 열쇠는 "추상적 인"것이 아니라 "상속을 염두에두고 설계 되었습니까?" 때로는 둘 사이에 상관 관계가 있지만 두 번째는 중요한 것입니다. 간단한 예제를 취하기 위해 대부분의 AWT 클래스는 추상적이지 않은 것도 확장되도록 설계되었습니다.

Bloch의 장의 요약은 조상이 상속되지 않도록 설계되지 않았다면 상속 수업의 상호 작용이 놀랍고 예측할 수 없다는 것입니다. 따라서 수업은 두 가지 종류로 제공되어야합니다. a) 확장되도록 설계된 클래스와 그것이 어떻게 해야하는지 설명하기에 충분한 문서가 있습니다. b) 최종적으로 표시됩니다. (a)의 수업은 종종 추상적이지만 항상 그런 것은 아닙니다. 을 위한

경우에 따라 서브 클래싱이 없는지 확인하려고합니다. 다른 경우에는 서브 클래스 (Abstract)를 보장하려고합니다. 그러나 원래 저자로서 당신이 신경 쓰지 않고 신경 쓰지 말아야하는 클래스의 큰 부분 집합이 항상 있습니다. 개방/폐쇄의 일부입니다. 무언가를 닫아야한다고 결정하는 것은입니다 또한 이유가 있습니다.

나는 동의하지 않는다. 계층이 나쁘면 객체 지향 언어가 존재할 이유가 없을 것입니다. Microsoft와 Sun의 UI 위젯 라이브러리를 보면 상속을 찾을 수 있습니다. 정의에 따라 모든 "나쁜 코드"입니까? 아니, 물론.

상속은 남용 될 수 있지만 언어 기능도 마찬가지입니다. 요령은 적절하게 일을하는 방법을 배우는 것입니다.

나는 더 이상 동의하지 않을 수 없었다. 클래스 계층 구조는 콘크리트 클래스에 대한 의미가 있습니다. 콘크리트 클래스가 최종적으로 표시되지 않은 가능한 반환 방법을 알고있을 때. 예를 들어, 콘크리트 클래스에는 서브 클래스 후크가있을 수 있습니다.

protected SomeType doSomething() {
return null;
}

이 복용량은 NULL 또는 SOMENTYPE 인스턴스로 보증됩니다. Songype 인스턴스를 처리 할 수는 있지만 현재 클래스에서 Sombervey 인스턴스를 사용하는 사용 사례가 없지만이 기능은 서브 클래스에있어서 실제로는 모든 것이 구체적이라는 것을 알고 있습니다. 널 값으로 아무것도하지 않는 기본값으로 직접 사용할 수 있다면 현재 클래스를 추상 클래스로 만드는 것은 의미가 없습니다. 당신이 그것을 추상적 인 수업으로 만들었다면, 당신은이 유형의 계층 구조에 아이들을 갖게 될 것입니다.

  • 초록 기본 클래스
    • 기본 클래스 (비 임금이었을 수있는 클래스는 보호 된 방법을 구현하고 다른 것도 구현합니다).
    • 다른 서브 클래스.

따라서 기본 클래스가 가장 일반적인 경우가 될 때 직접 사용할 수없는 추상 기본 클래스가 있습니다. 다른 계층 구조에는 클래스가 적은 클래스가 적으므로 추상화가 클래스에 강요되어야했기 때문에 본질적으로 쓸모없는 기본 클래스를 만들지 않고도 기능을 사용할 수 있습니다.

  • 기본 클래스
    • 다른 서브 클래스.

이제 계층 구조를 사용하고 학대 할 수 있으며, 사물이 명확하게 기록되지 않거나 클래스가 잘 설계되지 않은 경우 서브 클래스가 문제에 빠질 수 있습니다. 그러나 이러한 동일한 문제는 추상 수업에도 존재하며, 수업에 "초록"을 추가하기 때문에 문제를 제거하지 않습니다. 예를 들어, 위의 "dosomething ()"메소드의 계약이 getters and setters를 통해 액세스 할 때 x, y 및 z 필드를 채우도록 요구하는 경우 null을 반환 한 콘크리트 클래스를 사용한 경우 서브 클래스가 날아갑니다. 기본 클래스 또는 추상 클래스로.

클래스 계층 구조를 설계하기위한 일반적인 경험 법칙은 거의 간단한 질문입니다.

  1. 서브 클래스에 제안 된 슈퍼 클래스의 동작이 필요합니까? (Y/N) 이것은 스스로에게 물어봐야 할 첫 번째 질문입니다. 행동이 필요하지 않으면 서브 클래스에 대한 논쟁이 없습니다.

  2. 서브 클래스에 제안 된 슈퍼 클래스의 상태가 필요합니까? (Y/N) 이것은 두 번째 질문입니다. 상태가 필요한 것의 모델에 맞는 경우, 이것은 서브 클래싱을위한 canidate 일 수 있습니다.

  3. 서브 클래스가 제안 된 슈퍼 클래스에서 생성 된 경우, 실제로 IS-A 관계일까요, 아니면 행동과 상태를 상속하는 바로 가기입니까? 이것이 마지막 질문입니다. 단지 바로 가기 일고 제안 된 서브 클래스 "AS-A"슈퍼 클래스를받을 수없는 경우 상속을 피해야합니다. 상태와 논리는 다른 근본이있는 새 클래스에 복사하여 붙여 넣거나 위임을 사용할 수 있습니다.

클래스가 동작이 필요하고 상태가 필요하고 서브 클래스가 A (N) 슈퍼 클래스의 인스턴스가 슈퍼 클래스에서 상속되는 것으로 간주되어야한다고 생각할 수 있습니다. 그렇지 않으면, 목적에 더 적합한 다른 옵션이 존재하지만, 약간 더 많은 작업이 필요할 수 있지만 장기적으로는 더 깨끗합니다.

행동을 바꾸고 싶지 않은 경우가 몇 가지 있습니다. 예를 들어, 문자열 클래스, 수학.

나는 항상 똑같은 일을하는 더 좋은 방법이 있기 때문에 상속 재산을 좋아하지 않지만 거대한 시스템에서 유지 보수 변경을 할 때 때로는 최소한 변경으로 코드를 수정하는 가장 좋은 방법은 클래스를 약간 연장하는 것입니다. 그렇습니다. 일반적으로 나쁜 코드로 이어지지 만 코드가 작동하고 몇 달의 재 작성 없이는 코드로 이어집니다. 따라서 유지 보수 담당자에게 자신이 처리 할 수있는 유연성을주는 것이 좋은 방법입니다.

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