【发布时间】:2011-05-31 15:40:18
【问题描述】:
是否可以像在 C++ 中那样在 Java 中编写 virtual 方法?
或者,是否有一种适当的 Java 方法可以实现并产生类似的行为?我可以举一些例子吗?
【问题讨论】:
标签: java virtual virtual-functions
是否可以像在 C++ 中那样在 Java 中编写 virtual 方法?
或者,是否有一种适当的 Java 方法可以实现并产生类似的行为?我可以举一些例子吗?
【问题讨论】:
标签: java virtual virtual-functions
默认情况下,Java 中的所有函数都是虚函数。
您必须通过添加“final”关键字来编写非虚拟函数。
这与 C++/C# 默认设置相反。默认情况下,类函数是非虚拟的;您可以通过添加“虚拟”修饰符来制作它们。
【讨论】:
所有非私有实例方法在Java中默认是虚拟的。
在 C++ 中,私有方法可以是虚拟的。这可以用于非虚拟接口 (NVI) 习惯用法。在 Java 中,您需要保护 NVI 的可覆盖方法。
来自 Java 语言规范 v3:
8.4.8.1 覆盖(通过实例方法)实例方法 m1 在 C 类中声明的覆盖 声明了另一个实例方法 m2 如果满足以下所有条件,则属于 A 类 是真的:
- C 是 A 的子类。
- m1 的签名是签名的子签名(第 8.4.2 节) 平方米。
- 要么 * m2 是公共的、受保护的或声明为在 与 C 相同的包,或 * m1 覆盖一个方法 m3,m3 不同于 m1,m3 不同于 m2,这样 m3 会覆盖 m2。
【讨论】:
是的,您可以在 Java 中编写虚拟“函数”。
【讨论】:
是的。事实上,Java 中的所有实例方法在默认情况下都是虚拟的。只有某些方法不是虚拟的:
这里有一些例子:
“普通”虚函数
以下示例来自另一个答案中提到的维基百科页面的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 {}
输出:
我像普通动物一样吃东西。 我吃得像鱼! 我吃得像金鱼! 我像普通动物一样吃东西。带有接口的虚函数示例
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.
}
}
【讨论】:
在 Java 中,所有公共(非私有)变量和函数默认都是虚拟。 此外,使用关键字 final 的变量和函数不是 virtual。
【讨论】: