在Java中,如果返回类型分别是原始类型及其包装类,是不是可以覆盖方法?
Posted
技术标签:
【中文标题】在Java中,如果返回类型分别是原始类型及其包装类,是不是可以覆盖方法?【英文标题】:In Java, is it possible to override methods if return types are respectively a primitive and its wrapper class?在Java中,如果返回类型分别是原始类型及其包装类,是否可以覆盖方法? 【发布时间】:2014-12-30 07:10:04 【问题描述】:在使用 Java 中覆盖和覆盖方法的想法时,我注意到此类方法的返回类型具有一定的灵活性。
这里有一点理论: “派生类中覆盖方法的返回类型可以相同,也可以是基类中覆盖方法的返回类型的子类。这种覆盖方法的返回类型称为协变返回类型。”
下面的例子假设 B 扩展了 A。
Method in A:
public Object some_method() ....
Method in B:
public Integer some_method() ....
因此,我们看到 B 中的 some_method() 覆盖了 A 中的 some_method(),因为 Integer 是 Object 的子类。
我想知道是否存在以下灵活性,以及由于自动装箱和取消装箱,以下是否可以正常工作:
Method in A:
public Integer some_method() ....
Method in B:
public int some_method() ....
或
Method in A:
public int some_method() ....
Method in B:
public Integer some_method() ....
【问题讨论】:
不,你不能。但是你为什么不试试呢? 基元不是对象,因此它们不参与对象层次结构。不过,如果您需要类似的东西,您可以使用自动装箱。 Java 已经足够完善,您可以通过试用来验证这一点。 @markspace:问题不在于对象层次结构。我想知道如果返回类型与自动装箱/拆箱兼容,是否可以覆盖。 真的很简单,看你引用的部分:“派生类中覆盖方法的返回类型可以相同,也可以是返回类型的子类”,所以由于原语不是任何类的一部分,所以没有。 【参考方案1】:您只能返回相同类型或父返回类型的子类及其称为 Co-Variant 返回类型。
编译器允许您在原语和包装器之间自动装箱和拆箱,但这不会使一个成为另一个的子类。基元不是类,不能以您的方式使用。
【讨论】:
我喜欢你的回答。但我认为这是一个悖论。我认为应该更改 Java 规范,以便编译器允许它。【参考方案2】:这种灵活性是不存在的,因为“int”是原始数据类型,而“Integer”是 int 数据类型的类/包装器。并且“int”不是“Integer”的子类,而“Integer”是“Object”类的子类
【讨论】:
【参考方案3】:也许您将这个概念与overloading 混淆了。
重载描述了采用同名但参数不同的方法;在规范示例中,重载方法甚至可以返回不同的类型(尽管不鼓励这样做,因为它会降低代码的可读性)。
也就是说……这是合法的:
public int foo()
return 1;
public Integer foo(int multiplicand)
return 10 * multiplicand;
...因为你没有接触相同的方法。
在继承方案中,类似的代码将是非法的,根据Language Specification:
其中一个继承的方法必须是可替代所有其他继承方法的返回类型;否则,会发生编译时错误。
class Primary
public int foo()
return 1;
// no, this does not compile!
class Secondary extends Primary
@Override
public Integer foo()
return 1;
因此,如果父类型为 Object
(因为 Integer
is-an Object
由于继承),上述内容将有效,但它根本不适用于原语,因为它们不是对象。
自动装箱很好,因为它可以解决一些当我们只关心原始对象时不得不处理对象的烦恼,但这并不是万能的。它们的核心仍然是Object
s,它们仍然可以指向null
,而原语根本不能。
【讨论】:
谢谢。但我并没有混淆重载的概念。我知道在重载时,返回类型可能完全不同而且完全不相关。【参考方案4】:第一个例子:
Method in A:
public Object some_method() ....
Method in B:
public Integer some_method() ....
这种类型的覆盖是可能的,但是对于两个例子来说,覆盖是不可能的。
【讨论】:
以上是关于在Java中,如果返回类型分别是原始类型及其包装类,是不是可以覆盖方法?的主要内容,如果未能解决你的问题,请参考以下文章