나는 기본 수업이 Base있습니다. 그것은 두 개의 서브 클래스를 가지고 Sub1와 Sub2. 각 서브 클래스에는 몇 가지 추가 메소드가 있습니다. 예를 들어, Sub1has Sandwich makeASandwich(Ingredients... ingredients)및 Sub2has가 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같은 의미로 사용 할 수 없다, 왜 당신은 그런로 처리합니까? 왜 '샌드위치 제작자'와 '외계인 접촉자'를 따로 추적하지 않습니까?