繁体   English   中英

具有泛型返回类型的自引用方法,用于多个继承的类

[英]self-referential methods with generic return type for multiple inherited classes

描述可能有点困难。 但是,我会试试;)

遵循流畅的样式,类的方法通常返回类实例本身(this)。

public class A {

    public A doSomething() {

        // do something here

        return 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

}

但是,当在这个扩展类上做另一个继承步骤时,我在尝试定义方法的泛型返回类型(在上层类中)和类描述本身时遇到了麻烦,例如,超级超级中的方法class不会返回extend类的类型,而是返回超类的类型。 但是,我的意图是这些流畅的样式方法应该总是返回当前类的类型(而不是上层类)。

那么可以通过利用泛型来定义解决方案吗?

PS:我知道,一个简单的解决方法可能会覆盖扩展类中的所有这些方法并将它们转换为当前类型。 但是,我对更优雅的解决方案感兴趣;)

你可以尝试:

class A<T> { }

class B<T extends A<? super T>> extends A<T> { }

class C extends B<C> { }

你可以这样做:

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> {
}

这将返回:

TestFluent2@7919298d
TestFluent3@62f72617

一般来说,不可能“返回当前类的类型”。

即使你上面发布的代码也不安全: public class C extends A<B>是合法的,但是在它上面调用doSomething() ,期望一个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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM