我的A类是:
public class A {
int sayHello(int i,int j){
return i+j;
}
}
另一类B为:
public class B extends A {
@Override
int sayHello(int i, int j) {
return i+j;
}
}
如果我将类A的方法sayHello(int,int)的返回类型从int改为float,它会显示一个错误,因为根据覆盖规则,返回类型也被认为是无效的覆盖和重载。
我不明白为什么java不允许更改返回类型。为什么返回类型也需要相同
如图所示(强调我自己)
子类覆盖方法的能力允许类从行为“足够接近”的超类继承,然后根据需要修改行为。重写方法与它重写的方法具有相同的名称、参数数量和类型以及返回类型。重写方法也可以返回被重写方法返回的类型的子类型。这种子类型称为协变返回类型。
如果返回的类型不同,它会破坏其他类,这些类可以在运行时使用多态性来检测类的类型。
重写方法时可以更改返回类型:只需使用协变类型重写它即可。
例如,如果您将接口定义为:
interface Foo {
Object foo();
}
那么可以这样实施它:
class Bar implements Foo {
@Override public String foo() {
return "";
}
}
因为Foo的所有实现。foo()
必须返回一个Object
s,并且所有String
s都是
s。
但是,不能用另一种方法:如果返回类型Foo。foo()
是String
,您无法实现它来返回Object
,因为该方法的调用方需要能够在该实例上调用
的方法。例如:
void test(Foo instance) {
System.out.println(instance.foo().length());
}
如果返回了 Object
,这在运行时将不起作用,因为 Object
上没有 length()
方法。(但更具体地说,它必须是 String.length()
方法,而不仅仅是任何长度方法:Java 不支持鸭子类型)。编译器可以检测到这种不匹配,因此它会阻止您执行此操作。
int
没有类型协变(或任何原始类型),因此当您覆盖返回int
的方法时,您必须返回int
。
允许这样做的理论原因是Liskov替换原则,它可以解释为“子类型方法可以在它们接受的参数中更通用,在它们返回的类型中更具体”。
但是,Java不允许使用更通用的参数类型,因为它解决方法重载的方式。
因为:
class Parent {
int method() { return 1; }
}
class Child extends Parent {
float method() { return 1.0f; }
}
Parent p = new Child();
int myInt = p.method();
method()
返回什么?它应该是一个int
,因为家长
说它是一个int。但是儿童
返回一个浮点数
。那么你希望发生什么?JVM应该崩溃吗?
顺便说一下,你可以改变返回类型,但它必须是类型的子类型,被覆盖的方法返回。因此,您可以重写返回< code>Parent的方法,并使用< code>Child作为返回类型。
问题内容: 为什么无法覆盖静态方法? 如果可能,请使用示例。 问题答案: 覆盖取决于拥有类的实例。多态性的重点是可以对一个类进行子类化,并且实现那些子类的对象对于在超类中定义的相同方法(在子类中被重写)将具有不同的行为。静态方法未与类的任何实例相关联,因此该概念不适用。 影响Java设计的因素有两个。一个是对性能的关注:Smalltalk批评它太慢(垃圾回收和多态调用是其中的一部分),Java的创
问题内容: 作为ASP.NET MVC 2 Beta 2更新的一部分,默认情况下不允许JSON GET请求。看来您需要将字段设置为从控制器返回对象之前。 这背后的原因是什么?如果我正在使用JSON GET尝试进行一些远程验证,那么我应该使用其他技术吗? 问题答案: DenyGet默认的原因是在MSDN上,该链接提供了Phil Haack的博客 的详细信息。看起来像跨站点脚本漏洞。
我最近在浏览SurfaceView的android文档,我发现要获得实际的surface,你必须做以下事情: surface holder的文档在这里:https://developer . Android . com/reference/Android/view/surface holder . html 现在一个SurfaceHolder从getHolder()返回,然后你可以在那个支架上调用
问题内容: 这是我的代码,但是我没有得到方法如何接受类型作为返回值。如何运作?谁能解释一下这种方法的工作原理? 提前致谢 :) 问题答案: 好的,所以首先要做的是: 这是一个不断扩大的原始类型转换,因此这是合法的。您可以: 但是您不能: 第二:它返回的根本不是ASCII码。Java执行Unicode。 碰巧的是,当创建Java时,Unicode仅定义了适合16位的代码点。因此,它被创建为2字节的无
如果我在java中有一个抽象的(或据我所知的)超类,如下所示: 我注意到,在重写这个方法时,子类可以使用自身作为返回类型,但不能使用参数: 为什么不允许这样做?我不是在寻求解决方案——我知道我可以在方法中使用< code>instanceof检查或其他方法,我更想知道为什么前者是可以接受的,而后者对编译器来说却不是。
为什么允许使用memcpy指针更改常量变量? 此代码: 编译时只包含一个警告: 警告:传递“memcpy”的参数 1 将丢弃指针目标类型中的“const”限定符 [默认启用] 但运行得很好,并更改了常量变量的值。