考虑以下代码
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){...}
}
method()
? 考虑以下代码
Object someObj;
...
Number n= (Number) someObj;
在这种情况下,当我们转换为
Number
时,编译器在做什么?
为什么接口中不能定义静态方法?
接口的所有方法都是默认的
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
修饰符。
为什么接口中不能定义静态方法?
接口的设计基本上是为了与多态性一起工作。多态性 在接口上调用静态方法时,如何知道要调用哪个实现?
// Should that invoke MyClass.method or MyOtherImplementation.method?
MyInterface.method("foo");
下一个:
为什么我们不能用 static 修饰符实现 method() ?
这个想法是在实现接口的某个对象上调用该方法 - 这使其成为实例方法。
当我们引用 Object 调用 myMethod 时,会出现编译错误。据我了解,编译器不会自动转换,不是吗?
不,编译器不会自动转换。没有从
Object
到 Number
的隐式转换,因此您无法使用 Number
类型的参数调用具有 Object
类型参数的方法。
在这种情况下,当我们转换为 Number 时,编译器在做什么?
它验证
someObj
的值是否为 null 或者对 Number
实例或子类的引用。
直到 JDK7:
因为静态方法是绑定到类的。你通常这样调用它们:
MyClass.method("");
你不能覆盖它们。
见1,所有接口方法都是
public abstract
你无法改变!不,编译器不会自动转换
他尝试施法但失败了