繁体   English   中英

为什么Java只接受具有相同返回类型的重写基类方法?

[英]Why does Java only accept overridden base class method with the same return type?

我在C#中的背景。 我想知道为什么Java重写的基类方法期望相同的返回类型,即使我们将重写的返回类型更改为基类类型也会引发错误。 谁能让我知道原因呢? 请从下面找到代码片段。

public class ListIterator
     extends Test // Test is base for ListIterator
{
}

class Collection
{
    public ListIterator iterator() throws Exception {
        return new ListIterator();
    }
}


class Child 
    extends Collection
{
   //Here the return type “Test” is the base for ListIterator, but still it 
   //throws error to mark the return type as ListIterator. If we comment the 
   //extended base class "Collection" it works as expected.

    public Test iterator() throws Exception {
        return new ListIterator();
    }
}

首先,不,这在C#中不起作用-当您实际覆盖该方法时不行。 (如果您使用new ,它将起作用,但是您不必重写。)C#比Java更严格,因为返回类型必须完全匹配...而Java允许您返回更特定的类型,只是不是更一般的。 例如,这很好:

public class Base {
    public Object getFoo() {
        ...
    }
}

public class Child extends Base {
    @Override public String getFoo() {
        ...
    }
}

...但是您正试图做相反的事情。

为了说明为什么这样做很危险,请想象一下,您更改了Child.iterator()方法的实现以return new Test(); 然后想象有人写了:

Collection collection = new Child();
ListIterator iterator = collection.iterator();

一切看起来都是类型安全的,因为Collection.iterator()被声明为返回ListIterator ,但是返回的值既不是null也不是对ListIterator的引用。

因此,基本上,答案是“ Java可以保护您免于用脚射击。这是一件好事。”

子类型必须具有与其父类型相同或更大的功能。 正式地,这被称为Liskov替换原理

如果ListIterator扩展了Test ,则ListIterator可能比Test更强大,并且可能是Test ,否则它将毫无意义。

如果Child扩展Collection ,则Child一定不能通过从其方法之一返回性能较差的类型来降低Collection的功能。

如果这在C#中有效,则C#损坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM