说,我有以下代码(这是一个测验问题,所以我可以在我的IDE中运行它,但逻辑如何工作对我来说不太清楚):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
输出如下:
在A 中做某事
在A 中做某事
在A 中做某事
因此,我的第一个问题是:声明的含义是什么,如
A aInstance2 = new B();
即,为什么要创建一个B类对象,将其声明为A类的实例?与声明
相比,作为B类对象的aInstance2的属性如何变化B aInstance2 = new B();
如果我从类A,B和C中的方法doSth()的声明中删除 static 这个词,则输出变为
在A 中做某事
在B 中做某事
在C 中做某事
因此,当方法是静态的时,类A的方法doSth()没有被子类的方法覆盖,输出总是“在A中做某事”由不同类的对象,而当它成为一个实例(非静态)方法时,它被覆盖(如果我在这里使用正确的术语)。为什么会这样?
答案 0 :(得分:1)
删除静态这个词你正在做动态绑定,因为你几乎都在说:"尽管我知道这个对象属于A型,我希望它的行为像B"。
添加单词static意味着您正在使该方法成为类[引用类型]的一部分,并且每次调用时:" A dosmth()"他知道它只适用于A,所以它显示了A类的方法结果。
至于你会做什么?我从学校那里学到了这个功能,当我决定去采访时更加研究它;这是面试官想要看到的事情之一,如果你能处理的话
如果您不介意,我会发布一个包含静态和动态绑定信息的链接 http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
答案 1 :(得分:1)
因为静态方法基于参考类型。
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
所以在内部它转换为:
A.doSth();
A.doSth();
A.doSth();
答案 2 :(得分:1)
静态方法是类方法,而非静态方法是实例方法。因此,当您在实例上调用静态方法时,实际上是通过此实例的声明类型调用它。因此,以下所有调用实际上都执行相同的调用:A.doSth()
,因为所有实例都声明为类型A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
删除static关键字后,doSth()
方法将成为实例方法。实例方法是在对象而不是类上执行的。此外,当您在子类中重新声明实例方法时,此方法将被子类覆盖。在您的示例中,B类和C类覆盖doSth()
。因此,每个类都提供自己的实现。
答案 3 :(得分:1)
覆盖 取决于拥有类的实例。静态方法与类的任何实例都没有关联,因此该概念不适用。
使静态方法更快,因为没有必要等到运行时才能确定要调用哪种方法。
在Java中覆盖 只是意味着将根据对象的运行时类型调用特定方法,而不是基于它的编译时类型。
插图 -
当doSth()是静态的时:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
在上面的代码中,编译器将在编译时确定没有实例应该为A调用。否覆盖。
当doSth()不是静态时:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
在上面的代码中,编译器将在运行时决定该方法不是静态的,并且应该被相应的实例覆盖。
答案 4 :(得分:0)
静态方法处于class
级别并且作用于引用类型(LHS ==),而不像基于实例类型(RHS ==)动态分派的实例级方法