아이 빌더 전달 . 현재 그것은 Base
의 인스턴스를 반환하고 methodA()
이 Base
클래스에 존재하지 않는다는 오류를주는 것으로 보입니다.내가 뭔가를해야 경우가
GenericTypes의 일부 사례를이 경우 원하는 내용으로 보았습니다. 그러나 아직 구현하지 못했습니다. 모든 예제/포인터/링크 크게 감사하겠습니다.
감사합니다.
아이 빌더 전달 . 현재 그것은 Base
의 인스턴스를 반환하고 methodA()
이 Base
클래스에 존재하지 않는다는 오류를주는 것으로 보입니다.내가 뭔가를해야 경우가
GenericTypes의 일부 사례를이 경우 원하는 내용으로 보았습니다. 그러나 아직 구현하지 못했습니다. 모든 예제/포인터/링크 크게 감사하겠습니다.
감사합니다.
은 ChildA
으로 정의되었지만 getSibling
은 Base
을 반환하므로이 기능이 작동하지 않습니다. 이 Base
참조가 ChildA
개체를 가리 키지 만 명시 적 캐스팅을 수행하거나 Base
유형을 일반화해야합니다. 이 특별한 경우
getSibling
를 오버라이드 (override) 할 수 있습니다 :
ChildB
같은 클래스의 많은 생각이있는 경우
는
class ChildB extends Base {
public ChildB(ChildA sibling) {
super(sibling);
}
@Override
public ChildA getSibling() {
return (ChildA) super.getSibling();
}
}
이 잘 확장하지 않을 것입니다. 또한 ChildB
은 형제이므로 ChildA
만 포함하도록 제한됩니다.
편집 :
항상 당신이 그것을 대체 할 수 있습니다 일반 수
Base
클래스를 필요로하지 않는 당신을 가정 childB
좋아하지 않을 수 있습니다 :
class ChildB <T extends Base> extends Base {
public ChildB(T sibling) {
super(sibling);
}
@Override
@SuppressWarnings("unchecked")
public T getSibling() {
return (T) super.getSibling();
}
}
다음과 같이 지정하십시오 :
brother = new ChildB<ChildA>(this);
주조로하지 않는 한, 당신은 당신이 원하는 것을 할 수 없습니다
var child = new ChildA()
.getBrother() // ChildB
.someMethodX() // void
.someMethodY() // compile error
.getSibling() // compile error (someMethodY = void), Base
.methodA() // compile error, methodA does not exists on Base
.methodB() // idem.
을 나는 당신이 그 일을하는 두 가지 방법을 제안한다 :
Base
에 제네릭 형식, Base
할 수 있도록 Base
이 아닌 this
을 하위 유형으로 반환하십시오. ChildA
이 Base
으로 확장되고 두 가지 방법이 ChildA::setFoobar
, Base::setSaxon
인 경우 일괄 처리로 인해 builder.setSaxon("A").setFoobar("B")
이 가능합니다.
public class Base<B extends Base<B>> {
protected abstract B self();
public <C extends Base<C>> B setSibling(Base<C> base) {
this.sibling = base;
return self(); // or (B)this
}
}
public class ChildA extends Base<ChildA> {
protected ChildA self() {return this;}
}
public class ChildB extends Base<ChildB> {}
그리고이 작동합니다 다음 self
방법은 각 setXXX
방법 (B)this
에 캐스트를 피할 수
ChildA a = new ChildA().setSibling(new ChildB().setSibling(new ChildA()));
.
B 용 빌더 래퍼를 사용 : 그 중간 개체 ChildBBuilder
를 돌아 "최종"방법 getSibling()
이 속하는 ChildA
에 ChildB
의 새로운 인스턴스를 연결하고, 체인 계속 객체를 반환 :
public class ChildA extends Base{
private ChildB brother;
public ChildBBuilder getBrother() {
return new ChildBBuilder() {
public ChildA getSibling() {
ChildA.this.brother = create();
return ChildA.this;
}
};
}
}
public class ChildBBuilder {
public ChildBBuilder(ChildA parent) {
this.parent = parent;
}
... setter ...
public ChildB create() {
return new ChildB();
}
public ChildA getSibling() {
throw new UnsupportedOperationException();
}
}
을 ChildBBuilder
은 기본 구현이 실패하는 일부 getSibling 조작을 허용하는 독립 빌더입니다. 이 경우를 처리하기 위해 익명 추상 클래스를 만듭니다.
저는 이미 "기본 작성기"가있는 첫 번째 경우에 일부 프로젝트에서 사용되었습니다.
두 번째 경우에는 사용하지 않았습니다. 일부 작업에 대해 DSL을 만들려고 시도하는 경우 DSL이 유용 할지라도 그것이 가치있는 일을하는 것은 너무 많을 수 있음을 잊지 마십시오.
Java 8로 작업하는 경우 패턴을 순수 추상 구현 (see my answer here)으로 확장 할 수 있습니다.
ChildA로 전송하려고 했습니까? – lifus