클래스가 서브 클래스에 대해 알아야합니까?


24

클래스가 서브 클래스에 대해 알아야합니까? 예를 들어 클래스가 주어진 서브 클래스에 특정한 작업을 수행해야합니까?

내 본능은 나쁜 디자인이라고 말해줍니다. 그것은 일종의 반 패턴처럼 보입니다.


6
일반적으로 아니요, 그러나 특별한 경우에는 유용합니다.
코드 InChaos

이다 "리스 코프 치환 원칙"또는 때로는 LSP, 그것을 읽어 : 안티 패턴,라는 잘 알려진 하나 en.wikipedia.org/wiki/Liskov_substitution_principle
지미 호파

5
@JimmyHoffa- "Liskov 대체 원리"는 반 패턴의 이름이 아닙니다. 안티 패턴이 LSP를 위반할 수 있지만 이것이 사실인지는 확실하지 않습니다. 유형에 하위 유형이 있음을 알고 있더라도 하위 유형이 여전히 상위 및 반 분산으로 상위 유형으로 대체 될 수 있습니다.
Matthew Flynn

4
@MatthewFlynn 어쩌면 나는 LSP를 조금 느슨하게 사용하고 있지만 내 정의에 따르면 LSP를 준수하는 서로의 요구 사항을 모두 충족한다는 사실이 아닙니다. LSP를 위반하지 않는 다른 서브 클래스를 구현할 수 있습니다. 계층이 자체 인식 인 경우 외부 구현은 기본 클래스를 변경하지 않고 LSP를 충족 할 수 없습니다. 아마도 이것은 LSP가 아니지만 강력 할 것입니다. 그래 내가 말한해야 LSP의 위반이 반 패턴은
지미 호파

2
나는 이것을 몇 번 만났을 때, 그 지식을 서브 클래스에서 재정의 될 수있는 메소드로 리팩토링했다 (추상적이거나 순수한 가상으로 만들거나 재정의 할 수있는 합리적인 기본 구현을 제공함으로써 강제되었다).

답변:


32

클래스의 개념에 의해 암시 된 대답은 "아니오"입니다.

처리하는 작업, 데이터 또는 관계가 모든 하위 클래스의 일부이므로 실제 유형을 확인하지 않고 수퍼 클래스에서 처리해야합니다. 또는 일부 서브 클래스에만 적용됩니다. 그런 다음 올바른 유형을 수행하려면 런타임 유형 검사를 수행해야합니다. 다른 사람이 상속 할 때마다 수퍼 클래스를 변경해야합니다 (또는 자동으로 잘못된 일을 할 수 있음). 파생 클래스의 변경 사항은 변경되지 않은 수퍼 클래스 등을 손상시킬 수 있습니다.

요컨대, 이러한 솔루션을 거부 할 정도로 일반적으로 나쁜 여러 가지 나쁜 결과가 발생합니다. 여러 서브 클래스가 동일한 작업을 수행하고 코드 중복을 피하려면 (실제로는 항상 좋은 것), 더 나은 솔루션은 모든 서브 클래스가 코드를 상속 할 수있는 중간 레벨 클래스를 도입하는 것입니다.


4
이 규칙에 대한 한 가지 예외 : 클래스의 문서는 자체 서브 클래스를 자체 라이브러리에 로컬로 나열해야합니다.
Kieveli

3
@Kieveli ... 문서가 최신 상태 인 한.
mouviciel

14
유용한 문서 도구는 상속 트리를 그릴 수 있어야합니다.
johannes

13
나는 그것이 예외라고 생각하지 않습니다. 수업은 여전히 ​​아무것도 모른다. 설명서는 알고 있습니다.
혼자 브라 베스

4
@Kieveli uhh 나는 완전히 동의하지 않습니다.
지미 호파

16

뿐만 아니라 해야 그것을 모르고, 단순히 수 없습니다 ! 일반적으로 언제 어디서나 수업을 연장 할 수 있습니다. 그것은 쓰여질 때 조차 존재 하지 않았던 클래스에 의해 확장 될 수 있습니다 .

일부 언어에서는 수퍼 클래스에서 클래스 확장을 제어 할 수 있습니다. 스칼라에서 클래스는로 표시 될 수 있으며 sealed이는 동일한 컴파일 단위 (소스 파일) 내의 다른 클래스에 의해서만 확장 될 수 있음을 의미합니다. 그 서브 클래스가 아니라면 그러나, 또한 sealed 또는 final, 서브 클래스 다음 상기 다른 클래스로 확장 될 수있다.

스칼라에서는 닫힌 대수 데이터 유형을 모델링하는 데 사용되므로 표준 Haskell List유형은 다음과 같습니다.

data List a = Nil | Cons a (List a)

스칼라에서 다음과 같이 모델링 할 수 있습니다.

sealed trait List[+A]

case object Nil extends List[Nothing]

final case class Cons[+A] extends List[A]

그리고 당신은 보장 할 수 에만 있기 때문에이 두 하위 "클래스"존재를 List이고 sealed따라서 파일의 확장 밖에 할 수없는 Cons것입니다 final따라서 모두에서 확장 할 수 없습니다 및 Nil입니다 object어쨌든 확장 할 수 없습니다 수 있습니다.

그러나 이것은 특정 유스 케이스 (상속을 통해 대수 데이터 유형 모델링) 이며이 경우에도 수퍼 클래스는 실제로 서브 클래스에 대해 알지 못합니다. 그것은 더에 대한 보장의 사용자List그는의 경우 차별 않는 경우 해당 유형 NilCons어떤 없을 것 다른 자신의 뒤의 뒤에 진열 대안.


많은 언어에서 작동하는 것은 어떤 형태의 abstract internal멤버를 추가하는 것입니다 .
코드 InChaos

4

간단한 대답은 아니오입니다.

코드를 취 성화하고 객체 지향 프로그래밍의 두 가지 기본 원칙을 강조합니다.

  • 리스 코프 대체 원칙
  • 공개 원칙

1

예, 가끔 요 예를 들어, 제한된 수의 서브 클래스가 존재하는 경우. 방문자 패턴은 이 방법의 유용성의 그림입니다.

예 : 잘 정의 된 문법의 추상 구문 트리 (AST) 노드는 Node모든 노드 유형을 처리하기 위해 방문자 패턴을 구현하는 단일 클래스 에서 모두 상속 될 수 있습니다.


9
아냐 아냐 이것은 유용하지 않으며 결코 좋은 해결책이 아닙니다.
Sulthan

@Sulthan 나는 교실 밖에서 AST와 함께 일해 왔으며 lorus가 그 질문을 진정으로 이해하지 못한다고 생각합니다. 방문자는 AST의 노드 유형이 아니며 별도의 개체입니다. 문법 개체에 대해 알고 있어야합니다. 그러나 높은 수준의 AST 노드는 그렇지 않아야합니다.

1
@JohnGaughan "알다"라는 용어가 혼동됩니다. Node물론 기본 클래스에는 하위 클래스에 대한 직접 참조가 포함되어 있지 않습니다. 그러나 매개 변수 가있는 accept메소드가 포함되어 있습니다 Visitor. 그리고 각 서브 클래스 당 메소드를 Visitor포함합니다 visit. 따라서 Node서브 클래스에 대한 직접적인 참조는 없지만 Visitor인터페이스를 통해 간접적으로 서브 클래스를 "인식"합니다 . 그들은 모두 그것을 통해 함께 결합했습니다.
lorus

1
@Sulthan 절대 말하지 마십시오. 옵션 유형은 상위 클래스가 하위 클래스에 대해 알고있는 경우의 올바른 예입니다. 그러나 Jorg가 말했듯이 봉인 된 것으로 표시됩니다.
Pavel Voronin

그런 다음 동의합니다. 방문자는 방문하는 내용을 알아야합니다.

1

회사의 구성 요소를 작성한 후 나중에 떠난 후에 누군가가 해당 정보를 알려야하는 경우 자신의 목적을 위해 구성 요소를 확장 할 수 있습니까?

아니!

수업과 동일합니다. 너의 본능을 믿어 ​​봐.


고용 안정???
sixtyfootersdude

당신의 60 피트 높이는 내가 당신과 논쟁하지 않기 위해 :-) 그러나, 나는 나의 의미가 내가 가고 또 다른 직업을 얻은 후에 있기를 바랍니다.
다니엘 Hollinrake
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.