Answers:
在Java中,默认情况下,所有非静态方法都是“ 虚拟函数”。只有标记为final的方法(不能被覆盖)以及 私有方法(未继承)都是非虚拟的。
是。实际上,默认情况下,Java中的所有实例方法都是虚拟的。只有某些方法不是虚拟的:
这里有些例子:
“正常”虚拟功能
以下示例来自另一个答案中提到的Wikipedia页面的旧版本。
import java.util.*;
public class Animal 
{
   public void eat() 
   { 
      System.out.println("I eat like a generic Animal."); 
   }
   public static void main(String[] args) 
   {
      List<Animal> animals = new LinkedList<Animal>();
      animals.add(new Animal());
      animals.add(new Fish());
      animals.add(new Goldfish());
      animals.add(new OtherAnimal());
      for (Animal currentAnimal : animals) 
      {
         currentAnimal.eat();
      }
   }
}
class Fish extends Animal 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a fish!"); 
   }
}
class Goldfish extends Fish 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a goldfish!"); 
   }
}
class OtherAnimal extends Animal {}输出:
我像普通动物一样吃东西。 我吃得像鱼! 我吃得像一条金鱼! 我像普通动物一样吃东西。
带接口的虚函数示例
Java 接口方法都是虚拟的。它们必须是虚拟的,因为它们依赖于实现类来提供方法实现。仅在运行时选择要执行的代码。
例如:
interface Bicycle {         //the function applyBrakes() is virtual because
    void applyBrakes();     //functions in interfaces are designed to be 
}                           //overridden.
class ACMEBicycle implements Bicycle {
    public void applyBrakes(){               //Here we implement applyBrakes()
       System.out.println("Brakes applied"); //function
    }
}带有抽象类的虚函数示例。
与接口类似,抽象类 必须包含虚拟方法,因为它们依赖扩展类的实现。例如:
abstract class Dog {                   
    final void bark() {               //bark() is not virtual because it is 
        System.out.println("woof");   //final and if you tried to override it
    }                                 //you would get a compile time error.
    abstract void jump();             //jump() is a "pure" virtual function 
}                                     
class MyDog extends Dog{
    void jump(){
        System.out.println("boing");    //here jump() is being overridden
    }                                  
}
public class Runner {
    public static void main(String[] args) {
        Dog dog = new MyDog();       // Create a MyDog and assign to plain Dog variable
        dog.jump();                  // calling the virtual function.
                                     // MyDog.jump() will be executed 
                                     // although the variable is just a plain Dog.
    }
}Java中的所有功能默认情况下都是虚拟的。
您必须通过添加“ final”关键字来编写非虚拟函数。
这与C ++ / C#默认设置相反。默认情况下,类函数是非虚拟的;您可以通过添加“虚拟”修饰符来实现。
默认情况下,所有非私有实例方法在Java中都是虚拟的。
在C ++中,私有方法可以是虚拟的。可以将其用于非虚拟接口(NVI)习惯用法。在Java中,您需要使NVI可重写方法受到保护。
从Java语言规范v3:
8.4.8.1覆盖(通过实例方法)如果满足以下所有条件,则在类C中声明的实例方法m1将覆盖在类A中声明的另一个实例方法m2:
- C是A的子类。
- m1的签名是m2的签名的子签名(第8.4.2节)。
- * m2是公共的,受保护的或被声明为具有与C相同的程序包中的默认访问权限,或者* m1覆盖了方法m3,与m1不同的m3,与m2不同的m3,从而m3覆盖了m2。