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

问题描述 投票:0回答:7

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

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

java virtual virtual-functions
7个回答
355
投票

来自维基百科

Java中,所有非静态方法都是通过 仅默认“虚拟函数。” 带有关键字final标记的方法, 不能被覆盖,以及 私有方法,这不是 继承的,是非虚拟的


110
投票

你会用Java写虚函数吗?

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

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

以下是一些示例:

“普通”虚函数

以下示例来自另一个答案中提到的维基百科页面的“旧版本”。 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 中的所有函数默认都是虚函数。

60
投票

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

所有

非私有

9
投票

在 C++ 中,私有方法可以是虚拟的。这可以用于非虚拟接口 (NVI) 习惯用法。在 Java 中,您需要保护 NVI 可重写方法。 来自 Java 语言规范,v3:

8.4.8.1 重写(通过实例方法)实例方法 m1 在 C 类重写中声明 声明了另一个实例方法 m2 属于 A 类,当且仅当满足以下所有条件 是真的:

C 是 A 的子类。

m1 的签名是签名的子签名(§8.4.2) 平方米。
  1. 无论是 * m2 是公共的、受保护的或声明为具有默认访问权限 与 C 相同的包,或者 * m1 重写了 m3 方法,m3 与 m1 不同,m3 与 m3 不同 m2,这样 m3 就会覆盖 m2。
是的,你可以用Java编写虚拟“函数”。

4
投票

在 Java 中,所有公共(非私有)变量和函数默认都是

Virtual

1
投票
final

的变量和函数不是 virtual 在Java中,所有非静态、非私有方法默认都是虚拟的。这意味着它们可以在子类中被覆盖。 Java 不像 C++ 那样显式使用“virtual”关键字,因为方法重写是继承的固有特征。 有关此内容的更多详细信息,请阅读此博客:

Java 中的虚拟函数 | Java 中的运行时多态性

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.