Re: Chained call pattern with inheritance, polymorphism and generics...
Daniel Pitts wrote:
The point is, I shouldn't have to delegate to super just to return the
same reference as a different type.
While that IS currently the case, I wish it werent.
As already mentioned, you can still achieve that today.
Having a base builder declared as follows:
public abstract class BaseBuilder<T extends BaseBuilder<T>> {
protected abstract T nextBuilder();
public T something(String s) {
return nextBuilder();
}
}
One way to achieve your goal would be:
public abstract class SpecificBuilder<T extends SpecificBuilder<T>>
extends BaseBuilder<T> {
public static final class Instance extends SpecificBuilder<Instance> {
protected Instance nextBuilder() {
return this;
}
}
public T other() {
return nextBuilder();
}
}
public abstract class MoreSpecificBuilder<T extends
MoreSpecificBuilder<T>> extends SpecificBuilder<T> {
public static final class Instance extends
MoreSpecificBuilder<Instance> {
protected Instance nextBuilder() {
return this;
}
}
public T doMore() {
return nextBuilder();
}
}
With the following usage:
new SpecificBuilder.Instance().something("test").other();
new MoreSpecificBuilder.Instance().something("test").other().doMore();
Or use another way (the same as above, but more "classical" approach),
which exactly matches your usage scheme:
public abstract class SpecificBuilderBase<T extends
SpecificBuilderBase<T>> extends BaseBuilder<T> {
public T other() {
return thisBuilder();
}
}
public final class SpecificBuilder extends
SpecificBuilderBase<SpecificBuilder> {
protected SpecificBuilder thisBuilder() {
return this;
}
}
public abstract class MoreSpecificBuilderBase<T extends
MoreSpecificBuilderBase<T>> extends SpecificBuilderBase<T> {
public T doMore() {
return thisBuilder();
}
}
public final class MoreSpecificBuilder extends
MoreSpecificBuilderBase<MoreSpecificBuilder> {
protected MoreSpecificBuilder thisBuilder() {
return this;
}
}
Everything in that "pattern" depends on your needs. When you need
extendability of your concrete builder, you do provide an abstract
specialization with a default final realization as an option, otherwise
you just implement it as final class only (still preserving some
extendability of it in a future via delegation to super).
HTH,
piotr