Java在多级层次结构中继承了Fluent方法返回类型

时间:2013-10-17 02:05:03

标签: java generics inheritance fluent fluent-interface

遵循Java - Inherited Fluent method return type to return incident class' type, not parent's中描述的解决方案。我想将它扩展到多个层次。

解决方案显然在一个层面上工作。这是编译和可运行的代码(无依赖关系):

public enum X {
    ;
    static interface BaseFoo<T, S extends BaseFoo<T, S>> {
        S foo();
    }

    static interface Foo<T> extends BaseFoo<T, Foo<T>> {
        void foo1();
    }

    static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> {
        abstract void internalFoo();
        @Override
        public S foo() {
            internalFoo();
            return (S)this;
        }
    }

    static class FooImpl<T> extends AbstractFooBase<T, Foo<T>> implements Foo<T> {
        @Override
        void internalFoo() {
            System.out.println("inside FooImpl::internalFoo()");
        }

        @Override
        public void foo1() {
            System.out.println("inside FooImpl::foo1()");
        }
    }

    public static void main(String[] args) {
        Foo<String> foo = new FooImpl<String>();
        foo.foo().foo1();
    }
}

但是,当我在对象继承层次结构中添加新级别时,事情变得越来越困难。下面的代码不会编译:

public enum X {
    ;
    static interface BaseFoo<T, S extends BaseFoo<T, S>> {
        S foo();
    }

    static interface Foo<T> extends BaseFoo<T, Foo<T>> {
        void foo1();
    }

    static interface BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S> {
        S bar();
    }

    static interface Bar<T> extends BaseBar<T, Bar<T>> {
        void bar1();
    }

    static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> {
        abstract void internalFoo();
        @Override
        public S foo() {
            internalFoo();
            return (S)this;
        }
    }

    static class FooImpl<T> extends AbstractFooBase<T, Foo<T>> implements Foo<T> {
        @Override
        void internalFoo() {
            System.out.println("inside FooImpl::internalFoo()");
        }

        @Override
        public void foo1() {
            System.out.println("inside FooImpl::foo1()");
        }
    }

    static abstract class AbstractBarBase<T, S extends BaseBar<T, S>> extends FooImpl<T> implements BaseBar<T, S> {
        abstract void internalBar();
        @Override
        public S bar() {
            internalBar();
            return (S)this;
        }
    }

    static class BarImpl<T> extends AbstractBarBase<T, Bar<T>> implements Bar<T> {
        @Override
        void internalBar() {
            System.out.println("inside BarImpl::internalBar()");
        }

        @Override
        public void bar1() {
            System.out.println("inside BarImpl::bar1()");
        }
    }

    public static void main(String[] args) {
        Foo<String> foo = new FooImpl<String>();
        foo.foo().foo1();

        Bar<Boolean> bar = new BarImpl<Boolean>();
        bar.foo().bar1();
    }
}

编译时错误消息是:

X.java:40: X.BaseFoo cannot be inherited with different arguments: <T,S> and <T,X.Foo<T>>
    static abstract class AbstractBarBase<T, S extends BaseBar<T, S>> extends FooImpl<T> implements BaseBar<T, S> {
                    ^
X.java:49: X.BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>
    static class BarImpl<T> extends AbstractBarBase<T, Bar<T>> implements Bar<T> {
           ^
Note: X.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors

任何想法如何解决它?

1 个答案:

答案 0 :(得分:1)

这是您的继承层次结构:

inheritance hierarchy

如您所见,其中一些类型多次继承相同的接口类型。实际上,BarImpl实现了BaseFoo四次,并且一些继承链为其类型参数S提供了不同的参数。可以说BarImpl实现了以下内容:

  • BaseFoo<T, Foo<T>>(通过Foo
  • BaseFoo<T, Foo<T>>(通过FooImpl
  • BaseFoo<T, Bar<T>>(通过Bar
  • BaseFoo<T, Bar<T>>(通过BarImpl

The same interface cannot be implemented with different type arguments,因此您收到编译错误。

正如我在你的后续问题上指出的那样,我的回答here讨论了如何正确地模拟“自我类型”来实现像你想要的那样的层次化流畅的构建模式。在其中,我指出需要在所有中间类型中维护变量“自我类型”(代码中为S) - 仅使用被理解为{{1}的“叶类”来解析它}。您的代码违反了该规则,因为中间类型finalFooBar过早地解析了FooImpl

以下解决方案可解决此问题:

S

我的更改如下:

  • static interface BaseFoo<T, S extends BaseFoo<T, S>> { S foo(); } static interface Foo<T, S extends Foo<T, S>> extends BaseFoo<T, S> { void foo1(); } static interface BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S> { S bar(); } static interface Bar<T, S extends Bar<T, S>> extends BaseBar<T, S> { void bar1(); } static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> { abstract void internalFoo(); @Override public S foo() { internalFoo(); return (S)this; } } static abstract class AbstractIntermediateFoo<T, S extends AbstractIntermediateFoo<T, S>> extends AbstractFooBase<T, S> implements Foo<T, S> { @Override void internalFoo() { System.out.println("inside FooImpl::internalFoo()"); } @Override public void foo1() { System.out.println("inside FooImpl::foo1()"); } } static final class FooImpl<T> extends AbstractIntermediateFoo<T, FooImpl<T>> { } static abstract class AbstractBarBase<T, S extends AbstractBarBase<T, S>> extends AbstractIntermediateFoo<T, S> implements BaseBar<T, S> { abstract void internalBar(); @Override public S bar() { internalBar(); return (S)this; } } static final class BarImpl<T> extends AbstractBarBase<T, BarImpl<T>> implements Bar<T, BarImpl<T>> { @Override void internalBar() { System.out.println("inside BarImpl::internalBar()"); } @Override public void bar1() { System.out.println("inside BarImpl::bar1()"); } } public static void main(String[] args) { FooImpl<String> foo = new FooImpl<String>(); foo.foo().foo1(); BarImpl<Boolean> bar = new BarImpl<Boolean>(); bar.foo().bar1(); }
  • 中维护S
  • Foo
  • 中维护S
  • Bar拆分为以下内容:
    • FooImplAbstractIntermediateFoo,维护abstract,并实施SinternalFoo
    • foo1,具体,FooImpl,并解析final
  • 制作S BarImpl
  • final中,将mainfoo声明为barFooImpl - 此处的编码不可行。