【问题标题】:Rule for inheritance — return type of overriding method can be child class of return type declared in overridden method继承规则——覆盖方法的返回类型可以是被覆盖方法中声明的返回类型的子类
【发布时间】:2015-05-06 05:25:04
【问题描述】:

我正在查看继承规则。我遇到了以下规则

覆盖方法的返回类型可以是被覆盖方法中声明的返回类型的子类。

我不明白它背后的目的。 谁能解释一下。

【问题讨论】:

    标签: java inheritance


    【解决方案1】:

    它允许您在使用特定子类时使用更具体的返回类型。一个常见的示例是在覆盖 clone() 方法时使用更具体的返回类型。它被声明为

    protected native Object clone() throws CloneNotSupportedException;
    

    所以它返回Object。但是在您的特定班级(例如,MyObject)中,您可以像这样重新定义克隆:

    public MyObject clone() {
        try {
            return (MyObject)super.clone();
        }
        catch(CloneNotSupportedException ex) {
            throw new InternalError();
        }
    }
    

    这样MyObject 类的用户可以调用clone() 方法并获得MyObject 结果,而无需额外转换。挺方便的。

    【讨论】:

    • 很好的例子。当super.clone() 返回Object 类型时,您如何将super.clone() 向下转换为类型MyObject?换句话说,你怎么能将 Object 向下转换为 MyObject 类型?
    • @rb612 - 你总是可以做 explicit typecast / downcast 。您的代码将编译。但是如果类型是incompatible,那么在run-time,你会得到ClassCastException
    • 正如documentation 所说,super.clone() 调用会创建当前对象的新实例,无论它是什么。它是本机 JVM 代码,而 JVM 知道如何执行此操作。因此,您可以安全地将其转换为当前类。
    • 啊,我不知道 super.clone() 返回当前类的新克隆。为什么我们在 super 上调用 clone 方法而不是 this.clone()
    • 调用this.clone() 你将调用你所在的相同方法。这是无限递归。你会得到StackOverflowError
    【解决方案2】:

    好的,这就是我认为可能发生的事情。

    假设您有以下内容:

    public class Animal {
    ...
       public Animal anotherAnimal() {
          return new Animal();
       }
    }
    
    public class Dog extends Animal {
    ...
       public Dog anotherAnimal() {
          return new Dog();
       }
    }
    

    所以这里发生的事情是我们覆盖了超类方法anotherAnimal,规则是在子类(Dog)中,我们可以返回与超类方法不同的对象,但它有返回一个作为子类的对象。

    换句话说,因为DogAnimal 的子类,我们可以在重写的Dog 方法中返回它。

    【讨论】:

    • 另请注意,您不能降低被覆盖方法的可见性。即,孩子的 overriden 方法永远不能是 private
    • 我知道它,但它背后的逻辑目的是为什么它以这种方式实施
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2019-06-28
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多