class Base<SUB extends VariantA<SUB> & VariantB<SUB>> implements VariantA<SUB>, VariantB<SUB> {
public Base build() {
System.out.println("Building in Base class");
return this;
}
}
interface VariantA<SELF extends VariantA<SELF>> {
default SELF withVariantAParam(String param) {
System.out.println("Here in Variant A class with " + param);
return (SELF) this;
}
}
interface VariantB<SELF extends VariantB<SELF>> {
default SELF withVariantBParam(String param) {
System.out.println("Here in Variant B class with " + param);
return (SELF) this;
}
}
class Subclass extends Base<Subclass> {
public Subclass withSubclassParam(String param) {
System.out.println("Here in Subclass with " + param);
return this;
}
}
class AnotherSubclass extends Base<AnotherSubclass> {
public AnotherSubclass withAnotherSubclassParam(String param) {
System.out.println("Here in AnotherSubclass with " + param);
return this;
}
}
public class Client {
public static void main(String[] args) {
System.out.println("Subclass example:\n");
new Subclass()
.withSubclassParam("s1")
.withVariantAParam("foo")
.withSubclassParam("s2")
.withVariantBParam("bar")
.withSubclassParam("s3")
.build();
System.out.println("\n\nAnotherSubclass example:\n");
new AnotherSubclass()
.withAnotherSubclassParam("s1")
.withVariantAParam("foo")
.withAnotherSubclassParam("s2")
.withVariantBParam("bar")
.withAnotherSubclassParam("s3")
.build();
}
}