나는 기본 수업이 Base
있습니다. 그것은 두 개의 서브 클래스를 가지고 Sub1
와 Sub2
. 각 서브 클래스에는 몇 가지 추가 메소드가 있습니다. 예를 들어, Sub1
has Sandwich makeASandwich(Ingredients... ingredients)
및 Sub2
has가 boolean contactAliens(Frequency onFrequency)
있습니다.
이러한 방법은 다른 매개 변수를 사용하고 완전히 다른 작업을 수행하기 때문에 완전히 호환되지 않으며이 문제를 해결하기 위해 다형성을 사용할 수 없습니다.
Base
대부분의 기능을 제공하며 많은 Base
객체 모음이 있습니다. 그러나 모든 Base
객체는 a Sub1
또는 a Sub2
이며 때로는 어떤 객체 인지 알아야합니다.
다음을 수행하는 것은 나쁜 생각처럼 보입니다.
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
그래서 나는 캐스팅하지 않고 이것을 피하는 전략을 생각해 냈습니다. Base
이제 다음과 같은 방법이 있습니다.
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
물론 Sub1
이러한 방법을 다음과 같이 구현합니다.
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
그리고 Sub2
반대 방향으로 구현합니다.
불행하게도, 지금 Sub1
과 Sub2
자신의 API에서 이러한 방법이있다. 예를 들어 on에서이 작업을 수행 할 수 있습니다 Sub1
.
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
이런 식으로 객체가 오직로 알려진 경우 Base
, 이러한 메소드는 더 이상 사용되지 않으며 서브 클래스의 메소드를 호출 할 수 있도록 다른 유형으로 자신을 "캐스트"하는 데 사용될 수 있습니다. 이것은 나에게 우아해 보이지만 다른 한편으로는 클래스에서 메소드를 "제거"하는 방법으로 Deprecated 주석을 남용하고 있습니다.
때문에 Sub1
인스턴스가 정말 A는 자료, 그것은 사용 상속보다는 캡슐화 할 수 있도록 감각을한다. 내가 잘하고 있는거야? 이 문제를 해결하는 더 좋은 방법이 있습니까?
instanceof
, 입력을 많이 필요로 오류가 발생하기 쉬운, 그리고 열심히 더 서브 클래스를 추가 할 수있는 방법으로,.
Sub1
와 Sub2
같은 의미로 사용 할 수 없다, 왜 당신은 그런로 처리합니까? 왜 '샌드위치 제작자'와 '외계인 접촉자'를 따로 추적하지 않습니까?