Java 具有多个继承类的泛型返回类型的自引用方法
这可能有点难以描述。不过,我会试试;) 遵循fluent样式,类的方法通常返回类实例本身(如下所示) 当扩展这样一个fluent样式的类时,在第一个继承步骤中,通过泛型类型并在超类中将返回类型转换为这个泛型类型,可以相当容易地做到这一点Java 具有多个继承类的泛型返回类型的自引用方法,java,generics,inheritance,self-reference,Java,Generics,Inheritance,Self Reference,这可能有点难以描述。不过,我会试试;) 遵循fluent样式,类的方法通常返回类实例本身(如下所示) 当扩展这样一个fluent样式的类时,在第一个继承步骤中,通过泛型类型并在超类中将返回类型转换为这个泛型类型,可以相当容易地做到这一点 public class A<T extends A<T>> { public T doSomething() { // do something here return (T) this;
public class A<T extends A<T>> {
public T doSomething() {
// do something here
return (T) this;
}
}
public class B extends A<B> {
// an extended class of class A
}
公共A类{
公共卫生服务{
//在这里做点什么
返回(T)这个;
}
}
公共类B扩展了A{
//A类的扩展类
}
但是,在这个扩展类上执行另一个继承步骤时,我在尝试定义方法的泛型返回类型(在上层类中)和类描述本身时遇到了麻烦,例如,超级类中的方法不会返回扩展类的类型,而是返回超类的类型。然而,我的意图是这些fluent风格的方法应该总是返回当前类的类型(而不是上层类)
那么,是否有可能通过使用泛型来定义解决方案
PS:我知道,一个简单的解决方法可能是重写扩展类中的所有这些方法,并将它们强制转换为当前类型。但是,我对更优雅的解决方案感兴趣;) 您可以这样做:
public class TestFluent<T extends TestFluent<?>> {
public T get() {
return (T) this;
}
public static void main(final String[] args) {
TestFluent2<TestFluent2<?>> f2 = new TestFluent2<TestFluent2<?>>();
TestFluent2<?> result2 = f2.get();
TestFluent3<TestFluent3<?>> t3 = new TestFluent3<TestFluent3<?>>();
TestFluent3<?> result3 = t3.get();
System.out.println(result2);
System.out.println(result3);
}
}
class TestFluent2<T extends TestFluent2<?>> extends TestFluent<T> {
}
class TestFluent3<T extends TestFluent3<?>> extends TestFluent2<T> {
}
通常不可能“返回当前类的类型”
即使您在上面发布的代码也是不安全的:
public class C扩展了A
是合法的,但是在其上调用doSomething()
,期望AB
,将会崩溃。使用委派来实现可扩展的fluent接口。优点:没有演员。缺点:冗长
public interface FluentGranddad< C extends FluentGranddad< C > > {
C appendFoo( Foo foo );
}
public interface FluentDad< C extends FluentDad< C > > extends FluentGranddad< C > {
C appendBar( Bar b );
}
public interface FluentKid< C extends FluentKid< C > > extends FluentDad< C > {
C appendSplat( Splat s );
}
public class Babbler implements FluentKid< Babbler > {
FluentDad< ? > dad;
public Babbler( FluentDad< ? > dad ) {
this.dad = dad;
}
// delegation methods
@Override public Babbler appendFoo( Foo foo ) {
dad.appendFoo( foo );
return this;
}
@Override public Babbler appendBar( Bar bar ) {
dad.appendBar( bar );
return this;
}
// example instance method
@Override public Babbler appendSplat( Splat s ) {
dad.getState().append( s.toString() );
return this;
}
}
公共接口FluentGrandad>{
C附录Foo(Foo-Foo);
}
公共接口FluentDad>扩展FluentGrandad{
C.钢筋(钢筋b);
}
公共接口FluentKid>扩展FluentDad{
C附属物(附属物s);
}
公共类Babbler实现FluentKid{
FluentDad<?>dad;
公共唠叨者(FluentDad<?>dad){
这个。爸爸=爸爸;
}
//委托方式
@覆盖公共语言程序appendFoo(Foo-Foo){
爸爸,阿潘福(福);
归还这个;
}
@覆盖公共语言附加条(Bar){
爸爸,我是巴(巴);
归还这个;
}
//实例法
@覆盖公共语言附加程序(Splat s){
dad.getState().append(s.toString());
归还这个;
}
}
您可以尝试:
class A<T> { }
class B<T extends A<? super T>> extends A<T> { }
class C extends B<C> { }
class A{}
B类可能相关的问题:是的,我知道这是我目前应用的简单解决方法。然而,在引入新的扩展层时,总是重复这一点有点麻烦(从我的观点来看)。是的,这看起来有点前途。我以前也尝试过使用通配符,但还没有找到合适的解决方案。。。。因为它是公共类B扩展A,而不是公共类C扩展A;)我的意思是,定义公共类C扩展A
之后,定义公共类B扩展A
是合法的,不是吗?。。。当然,这是合法的。但是,它没有导致预期的行为,或者?(…无论如何…)然后当你做cfoo=。。。;B bar=食物剂量()代码>它将崩溃。所以这是不安全的,这不是我想做的:我想做:B foo=。。。;foo.doSomething().doSomethingElse().doSomethingDifferent()。。。所以它总是返回B(自引用)。因此,请不要将所描述的用例与其他东西混淆。
public interface FluentGranddad< C extends FluentGranddad< C > > {
C appendFoo( Foo foo );
}
public interface FluentDad< C extends FluentDad< C > > extends FluentGranddad< C > {
C appendBar( Bar b );
}
public interface FluentKid< C extends FluentKid< C > > extends FluentDad< C > {
C appendSplat( Splat s );
}
public class Babbler implements FluentKid< Babbler > {
FluentDad< ? > dad;
public Babbler( FluentDad< ? > dad ) {
this.dad = dad;
}
// delegation methods
@Override public Babbler appendFoo( Foo foo ) {
dad.appendFoo( foo );
return this;
}
@Override public Babbler appendBar( Bar bar ) {
dad.appendBar( bar );
return this;
}
// example instance method
@Override public Babbler appendSplat( Splat s ) {
dad.getState().append( s.toString() );
return this;
}
}
class A<T> { }
class B<T extends A<? super T>> extends A<T> { }
class C extends B<C> { }