我对Java中的继承方法中的返回类型有疑问。我有一个班级和一个继承的班级。在继承的类中,有一个特定的方法。它还从父类继承一个返回其自身实例的方法。
我想要这样的类层次结构:
public class Foo {
public Foo bar()
{
return this;
}
}
public class FooInherited extends Foo {
public Whatever baz()
{
return new Whatever();
}
}
我的问题是,我是否可以从其实例调用继承的方法,然后调用特定的方法而不重写方法以返回继承的类或显式地转换类。
现在我想要一个像这样的代码片段:
FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();
我觉得这很困难,但我不确定Java是否在这种情况下为程序员节省了时间。
答案 0 :(得分:4)
你可以使用泛型,但很快就会变得难看。
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
}
另一种方法是明确覆盖该方法:
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
}
答案 1 :(得分:4)
除非你重写子类中的方法,否则你必须强制转换:
FooInherited foo = new FooInherited();
Whatever w = ((FooInherited)foo.bar()).baz();
但是,由于java中的covariant return types,您可以像这样覆盖它:
public class FooInherited extends Foo {
@Override
public FooInherited bar()
{
return this;
}
...
}
覆盖后,您不再需要进行强制转换,因为foo的静态类型为FooInherited
:
FooInherited foo = new FooInherited();
Whatever w = foo.bar().baz();
答案 2 :(得分:1)
foo.bar()
返回Foo
个实例,但没有名为baz()
的方法,
因此无法编译此声明:Whatever w = foo.bar().baz();