在面向对象的范例中,虚拟函数或虚方法是一种函数或方法,其行为可以通过具有相同签名的函数在继承类中重写,以提供多态行为
根据定义,除了最终和私有方法之外,Java中的每个非静态方法都默认为虚方法。 多态行为无法继承的方法是不虚拟方法。
Java中的抽象类只不过是与C ++等效的纯虚方法。
为什么我们说Java中的静态方法不是虚方法?即使我们可以覆盖静态方法,因此它可以提供多态性的一些优点,并且Java中的静态方法也可以主要使用它的相关类名调用,但它也是可能的使用 Java 中它的关联类的对象来调用它,其方式与调用实例方法的方式相同。
答案 0 :(得分:17)
你无法覆盖静态方法。它们在编译时受到约束。它们不多态。即使您尝试调用它就像它是一个实例方法(您不应该执行IMO),它也绑定到该表达式的编译时类型,并且完全忽略执行时间值(即使它为null) :
Thread otherThread = null;
otherThread.sleep(1000); // No errors, equivalent to Thread.sleep(1000);
这种行为对于读者来说可能非常混乱,这就是为什么至少某些 IDE允许您生成警告或错误,以便“通过”引用访问静态成员。这是Java设计中的一个缺陷,纯粹而简单 - 但它根本不会使静态方法变得虚拟。
答案 1 :(得分:3)
很简单,静态方法不能被继承类覆盖,因为它不是继承的。所以这不是虚拟的。
你所谓的“覆盖静态方法”实际上只是在另一个类上定义另一个静态方法。它只会“隐藏”(这实际上是一个比实际上更真实的词)另一个,而不是覆盖它。
答案 2 :(得分:3)
Java中的抽象类只不过是与C ++等效的纯虚方法。
一个类不是一个方法。抽象类不必具有“虚拟”或抽象方法,甚至任何方法。
C ++开发人员放弃了Java功能,就像重新命名C ++而不理解差异一样。 ;)
为什么我们说Java中的静态方法不是虚方法?
不确定是谁说的,但static
方法不是多态的。
即使我们可以覆盖静态方法
我们不能,你只能隐藏或重载静态方法。
无论是使用类,子类还是实例来调用静态方法,都会忽略实际的类或实例。例如你可以做到
((Thread) null).yield();
答案 3 :(得分:3)
因为多态性适用于对象,而静态方法不涉及任何对象(但是与类相关)。
答案 4 :(得分:3)
假设您有A类
public class A
{
public static void doAStaticThing()
{
System.out.println("In class A");
}
}
和B
public class B extends A
{
public static void doAStaticThing()
{
System.out.println("In class B");
}
}
另一个类中的方法如下:
public void foo()
{
B aB = new B();
bar(B);
}
public void bar(A anA)
{
anA.doAStaticThing(); // gives a warning in Eclipse
}
您将在控制台上看到的消息是
In class A
编译器查看了方法栏中声明的anA
类型,并静态绑定到类A的doAStaticThing()
实现。该方法不是虚拟的。