考虑以下代码
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
时,编译器正在做什么?
答案 0 :(得分: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
修饰符。
答案 1 :(得分:2)
为什么我们不能在接口中定义静态方法?
接口设计用于处理多态,基本上。多态性在接口上调用静态方法时,您如何知道要调用哪个实现?
// Should that invoke MyClass.method or MyOtherImplementation.method?
MyInterface.method("foo");
下一步:
为什么我们不能用static修饰符实现method()?
这个想法是在一些实现接口的对象上调用该方法 - 这使它成为一个实例方法。
当我们通过引用Object调用myMethod时,我们有编译错误。据我所知,编译器不会自动转换,不是吗?
不,编译器不会自动转换。没有从Object
到Number
的隐式转换,因此您无法使用类型为Number
的参数调用类型为Object
的参数的方法。
在这种情况下,当我们转换为Number时,编译器正在做什么?
验证someObj
的值是null还是对Number
实例或子类的引用。
答案 2 :(得分:0)
直到JDK7:
因为静态方法绑定到类。你正常地像这样调用它们:
MyClass.method("");
你无法覆盖它们。
请参阅1,所有界面方法均为public abstract
,您无法更改!
编译器没有自动投射
他试图施放并失败