在Java中是否可能编写虚拟方法,就像在C++中一样?
或者,是否有适当的Java方法可以实现类似的行为?请提供一些示例。
在Java中是否可能编写虚拟方法,就像在C++中一样?
或者,是否有适当的Java方法可以实现类似的行为?请提供一些示例。
在Java中,所有非静态方法默认都是"虚函数"。 只有被标记为final关键字(无法重写)和私有方法(不会被继承)的方法是非虚函数。
能。实际上,Java中的所有实例方法默认都是虚拟的。只有一些方法不是虚拟的:
以下是一些示例:
"普通"虚函数
以下示例来自另一个答案中提到的维基百科页面的旧版本。
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#的默认相反。在C++/C#中,类函数默认为非虚函数;您需要添加"virtual"修饰符才能使它们成为虚函数。
在Java中,所有非私有实例方法默认为虚方法。
C++中,私有方法可以是虚的。这可以被用于非虚拟接口(NVI)惯用语。在Java中,您需要将NVI可重写方法设置为受保护的。
根据Java语言规范v3:
8.4.8.1 重写(通过实例方法)如果类C中声明的实例方法m1覆盖了类A中声明的另一个实例方法m2,则当且仅当以下条件均为 true 时,m1才会覆盖m2:
- C是A的子类。
- m1的签名是m2签名的子签名(§8.4.2)。
- 要么 * m2是公共的、受保护的或在与C相同的包中具有默认访问权限,要么 * m1覆盖一个方法m3,m3与m1不同,m3与m2不同,使得m3覆盖了m2。
Base
的类,其中包含some
方法,以及扩展Base
并具有其自己的实现some
方法的Derived
类,该方法由final
保留字标记。some
方法仍然是虚拟的。 - Andrey