你能用Java编写虚函数/方法吗?

时间:2010-12-28 16:17:58

标签: java virtual virtual-functions

是否可以在Java中编写虚拟方法,就像在C ++中一样?

或者,是否有适当的Java方法可以实现,产生类似的行为?我能举一些例子吗?

6 个答案:

答案 0 :(得分:269)

来自wikipedia

  

Java 中,所有非静态方法都是   默认“虚拟功能。”仅限   标有关键字final 的方法,   这是不能被覆盖的   私有方法,但不是   继承,非虚拟

答案 1 :(得分:87)

您能用Java编写虚函数吗?

是。实际上,Java中的所有实例方法都是默认的虚拟方法。只有某些方法不是虚拟的:

  • 类方法(因为通常每个实例都保存有关其特定方法的指向vtable的信息,但此处没有实例可用。)
  • 私有实例方法(因为没有其他类可以访问该方法,调用实例始终是定义类本身的类型,因此在编译时明确知道)。

以下是一些例子:

“正常”虚拟功能

以下示例来自另一个答案中提到的维基百科页面的old version

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 {}

输出:

I eat like a generic Animal.
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.

带接口的示例

Java interface methods都是虚拟的。它们必须是虚拟的,因为它们依赖于实现类来提供方法实现。要执行的代码只能在运行时选择。

例如:

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 classes 必须包含虚方法,因为它们依赖于扩展类的实现。例如:

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.
    }
}

答案 2 :(得分:54)

默认情况下,Java中的所有函数都是虚拟的。

您必须通过添加“final”关键字来编写非虚拟函数。

这与C ++ / C#默认相反。默认情况下,类函数是非虚拟的;你可以通过添加“虚拟”修饰符来实现它们。

答案 3 :(得分:9)

默认情况下,所有非私有实例方法在Java中都是虚拟的。

在C ++中,私有方法可以是虚拟的。这可以用于非虚拟接口(NVI)习语。在Java中,您需要保护NVI可覆盖方法。

从Java语言规范,v3:

  

8.4.8.1覆盖(通过实例方法)实例方法m1   在C类中声明覆盖   声明了另一个实例方法m2   在A类中如果以下所有内容   是的:

     
      
  1. C是A的子类。
  2.   
  3. m1的签名是签名的子签名(第8.4.2节)   是m2。
  4.   
  5. 要么         * m2是公共的,受保护的或声明的默认访问权限   与C相同的包装,或         * m1覆盖方法m3,m3与m1不同,m3与m3不同   m2,m3超越m2。
  6.   

答案 4 :(得分:2)

是的,您可以用Java编写虚拟“函数”。

答案 5 :(得分:0)

在Java中,所有公共(非私人)变量&amp;默认情况下,函数是虚拟。 此外,变量&amp;使用关键字最终的功能不是虚拟