实现接口方法、方法调用和类型转换

问题描述 投票:0回答:3

考虑以下代码

interface MyInterface{
    void method(String s);// if we write static modifier we have compile error
}
class MyClass implements MyInterface{
    public static void main(String[] args){
        myMethod(new Object());//Compile error
    }
    static void method(String s){...}// compile error
    static void myMethod(Number n){...}

}
  1. 为什么接口中不能定义静态方法?
  2. 为什么我们不能用 static 修饰符实现
    method()
  3. 当我们引用 Object 调用 myMethod 时,会出现编译错误。据我了解,编译器不会自动转换,不是吗?
  4. 考虑以下代码

    Object someObj; 
    ...
    Number n= (Number) someObj;

在这种情况下,当我们转换为

Number
时,编译器在做什么?

java
3个回答
4
投票

为什么接口中不能定义静态方法?

接口的所有方法都是默认的

public abstract
。使用
static
修饰符没有意义。因为静态方法的调用不是多态的。从某种意义上说,你无法覆盖它们。您仅调用类名上的静态方法。好吧,您也可以在某些引用上调用它们,但这最终将根据引用的声明类型来解决。现在,由于该方法默认是抽象的,因此调用它没有意义。它没有任何身体来执行任何任务。

为什么我们不能用 static 修饰符实现 method() ?

当您尝试将

static
修饰符添加到重写的方法时,它不会被视为被重写。因此,您的类本质上有两个不同的方法,具有相同的名称、相同的参数和相同的返回类型。这在课堂上当然是不允许的。

请注意,您必须在类中的重写方法中显式添加

public
修饰符,否则您的代码将无法编译。原因是,您无法降低子类中重写方法的可见性。

当我们引用 Object 调用 myMethod 时,会出现编译错误。据我了解,编译器不会自动转换,不是吗?

Jave 不进行自动缩小转换。您需要显式添加强制转换。但即使它允许,您期望代码的行为如何,因为您试图使用子类引用来引用超类对象?当然,您可以通过在调用方法时添加强制转换来编译代码:

myMethod((Number)new Object());  // This will compile, but fail at runtime

上述调用将在运行时产生

ClassCastException

但是,如果您有一个

Object
引用引用
Number
的任何子类的对象,则可以添加显式强制转换,这将是类型安全的:

Object obj = new Integer(5);
Number num = (Number)obj;  // This is fine. Because `obj` is referring to an `Integer`.

最后,您的

main
方法的签名不正确。您缺少
public
修饰符。


2
投票

为什么接口中不能定义静态方法?

接口的设计基本上是为了与多态性一起工作。多态性 在接口上调用静态方法时,如何知道要调用哪个实现?

// Should that invoke MyClass.method or MyOtherImplementation.method?
MyInterface.method("foo");

下一个:

为什么我们不能用 static 修饰符实现 method() ?

这个想法是在实现接口的某个对象上调用该方法 - 这使其成为实例方法。

当我们引用 Object 调用 myMethod 时,会出现编译错误。据我了解,编译器不会自动转换,不是吗?

不,编译器不会自动转换。没有从

Object
Number
的隐式转换,因此您无法使用
Number
类型的参数调用具有
Object
类型参数的方法。

在这种情况下,当我们转换为 Number 时,编译器在做什么?

它验证

someObj
的值是否为 null 或者对
Number
实例或子类的引用。


0
投票

直到 JDK7:

  1. 因为静态方法是绑定到类的。你通常这样调用它们:

    MyClass.method("");
    

    你不能覆盖它们。

  2. 见1,所有接口方法都是

    public abstract
    你无法改变!

  3. 不,编译器不会自动转换

  4. 他尝试施法但失败了

© www.soinside.com 2019 - 2024. All rights reserved.