Java继承的返回类型

Dan*_*ahr 6 java inheritance return-type

我有一个关于Java继承方法中的返回类型的问题。我有一个课和一个继承的课。在继承的类中,有一个特定的方法。它还从父类继承了一个返回其自身实例的方法。

我想要这样的类层次结构:

public class Foo {
    public Foo bar()
    {
        return this;
    }
}

public class FooInherited extends Foo {
    public Whatever baz()
    {
        return new Whatever();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否可以从其实例调用继承的方法,然后再调用特定的方法而不覆盖该方法以返回继承的类或显式转换类。

现在我想要一个这样的代码片段:

FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();
Run Code Online (Sandbox Code Playgroud)

我对此感到困难,但是我不确定在这种情况下Java是否为程序员提供了节省时间的机制。

Cep*_*pod 5

您可以使用泛型,但是很快就会很难看。

class Base<This extends Base<This>> {

    public This myself() {
        return (This) this;
    }

}

class Sub<This extends Sub<This>> extends Base<This> {

    public void subOnly() {}

}

{
    Sub<?> sub = new Sub<>();
    sub.myself().subOnly();
    Base<?> base = sub;
    // base.myself().subOnly(); // compile error
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是显式重写该方法:

class Base {

    public Base myself() {
        return this;
    }

}

class Sub extends Base {

    @Override
    public Sub myself() {
        return this; // or return (Sub) super.myself();
    }

    public void subOnly() {}

}

{
    Sub sub = new Sub();
    sub.myself().subOnly();
    Base base = sub;
    // base.myself().subOnly(); // compile error
}
Run Code Online (Sandbox Code Playgroud)


cyo*_*yon 4

除非您重写子类中的方法,否则您必须进行强制转换:

FooInherited foo = new FooInherited();
Whatever w = ((FooInherited)foo.bar()).baz();
Run Code Online (Sandbox Code Playgroud)

但是,由于java 中的协变返回类型,您可以像这样覆盖它:

public class FooInherited extends Foo {


        @Override
        public FooInherited bar()
        {
            return this;
        }
 ...
 }
Run Code Online (Sandbox Code Playgroud)

重写后,您不再需要强制转换,因为 foo 的静态类型是FooInherited

FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();
Run Code Online (Sandbox Code Playgroud)