是否可以像在 C++ 中那样在 Java 中编写虚拟方法?
或者,是否有一种合适的 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 中的所有函数默认都是虚函数。
这与 C++/C# 默认值相反。 类函数默认是非虚函数;你可以通过添加“虚拟”修饰符来实现它们。
所有
非私有在 C++ 中,私有方法可以是虚拟的。这可以用于非虚拟接口 (NVI) 习惯用法。在 Java 中,您需要保护 NVI 可重写方法。 来自 Java 语言规范,v3:
8.4.8.1 重写(通过实例方法)实例方法 m1 在 C 类重写中声明 声明了另一个实例方法 m2 属于 A 类,当且仅当满足以下所有条件 是真的:
C 是 A 的子类。m1 的签名是签名的子签名(§8.4.2) 平方米。
是的,你可以用Java编写虚拟“函数”。
- 无论是 * m2 是公共的、受保护的或声明为具有默认访问权限 与 C 相同的包,或者 * m1 重写了 m3 方法,m3 与 m1 不同,m3 与 m3 不同 m2,这样 m3 就会覆盖 m2。
在 Java 中,所有公共(非私有)变量和函数默认都是
Virtual的变量和函数不是 virtual。 在Java中,所有非静态、非私有方法默认都是虚拟的。这意味着它们可以在子类中被覆盖。 Java 不像 C++ 那样显式使用“virtual”关键字,因为方法重写是继承的固有特征。 有关此内容的更多详细信息,请阅读此博客:
Java 中的虚拟函数 | Java 中的运行时多态性