细化子类中方法的返回类型

发布于 2024-12-07 04:08:26 字数 618 浏览 0 评论 0原文

假设我有以下两个类:

  public class A {
    protected A create() {
      return new A();
    }

    public A f() {
      return create();
    }
  }

  public class B extends A {
    @Override
    protected B create() {
      return new B();
    }
  }

因此,如果我在 A 的实例上调用 f(),它将返回另一个 A。如果我在 B 的实例上调用 f(),它将返回另一个 B,因为 B.create () 方法将从 Af() 中调用。但是,B 上的 f() 方法被定义为返回 A 类型的对象。因此此代码将无法编译:

A a1 = new A();
B b1 = new B();

A a2 = a1.f();
B b2 = b1.f(); //Type mismatch: cannot convert from A to B

无需重写 B 类中的 f() 方法,有什么方法可以让 Af() 返回A,而 Bf() 返回 B?我已经用泛型搞砸了很多,但总是碰壁。

Say I have the following two classes:

  public class A {
    protected A create() {
      return new A();
    }

    public A f() {
      return create();
    }
  }

  public class B extends A {
    @Override
    protected B create() {
      return new B();
    }
  }

So if I call f() on an instance of A, it will return another A. And if I call f() on an instance of B, it will return another B since the B.create() method will be called from A.f(). But, the f() method on B is defined to return an object of type A. so this code will not compile:

A a1 = new A();
B b1 = new B();

A a2 = a1.f();
B b2 = b1.f(); //Type mismatch: cannot convert from A to B

Without having to override the f() method in class B, is there any way I can have A.f() return A, while B.f() returns a B? I've messed around a lot with generics but keep hitting a wall.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

早乙女 2024-12-14 04:08:27

我认为您被自己的代码绊倒了。 create 函数与 f 函数让您感到困惑。编译结果如下:

class demo {
    public class A {
        protected A create() {
            return new A();
        }
    }

    public class B extends A {
        protected B create() {
            return new B();
        }
    }
    void d() { 
        A a1 = new A();
        B b1 = new B();

        A a2 = a1.create();
        B b2 = b1.create(); 
    }
}

当协变体 create 隐藏在非协变体 f 后面时,编译器无法“运行”f 函数并证明它总是返回 B。

I think you've tripped over your own code. The create function versus the f function was confusing you. The following compiles:

class demo {
    public class A {
        protected A create() {
            return new A();
        }
    }

    public class B extends A {
        protected B create() {
            return new B();
        }
    }
    void d() { 
        A a1 = new A();
        B b1 = new B();

        A a2 = a1.create();
        B b2 = b1.create(); 
    }
}

When the co-variant create was hidden behind the non-co-variant f, the compiler couldn't "run" the f function and prove it would always return a B.

睫毛溺水了 2024-12-14 04:08:27

您还必须重写 f() - 您的版本调用返回 A 的方法。

public class B extends A {
    @Override
    protected B create() {
        return new B();
    }
    @Override
    public B f() {
        return create();
    }
}

You would also have to override f() as well - your version calls a method that returns A.

public class B extends A {
    @Override
    protected B create() {
        return new B();
    }
    @Override
    public B f() {
        return create();
    }
}
孤者何惧 2024-12-14 04:08:26

无需重写 B 类中的 f() 方法,有什么方法可以让 Af() 返回 A,而 Bf() 返回 B?

唯一的问题是在你的问题的最后一行代码。只是改变

B b2 = b1.f();
// to
A b2 = b1.f();

Without having to override the f() method in class B, is there any way I can have A.f() return A, while B.f() returns a B?

The only problem is in the very last line of code in your question. Just change

B b2 = b1.f();
// to
A b2 = b1.f();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文