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

发布于 2024-10-09 14:49:20 字数 96 浏览 4 评论 0原文

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

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

Is it possible to write virtual methods in Java, as one would do in C++?

Or, is there a proper Java approach which you can implement that produces similar behavior? Could I please have some examples?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

悍妇囚夫 2024-10-16 14:49:20

来自 维基百科

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

From wikipedia

In Java, all non-static methods are by
default "virtual functions." Only
methods marked with the keyword final,
which cannot be overridden, along with
private methods, which are not
inherited, are non-virtual.

南风几经秋 2024-10-16 14:49:20

你会用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 {}

输出:

I eat like a generic Animal.
I eat like a fish!
I eat like a goldfish!
I eat like a generic 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.
    }
}

Can you write virtual functions in Java?

Yes. In fact, all instance methods in Java are virtual by default. Only certain methods are not virtual:

  • Class methods (because typically each instance holds information like a pointer to a vtable about its specific methods, but no instance is available here).
  • Private instance methods (because no other class can access the method, the calling instance has always the type of the defining class itself and is therefore unambiguously known at compile time).

Here are some examples:

"Normal" virtual functions

The following example is from an old version of the wikipedia page mentioned in another answer.

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

Output:

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

Example with virtual functions with interfaces

Java interface methods are all virtual. They must be virtual because they rely on the implementing classes to provide the method implementations. The code to execute will only be selected at run time.

For example:

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

Example with virtual functions with abstract classes.

Similar to interfaces Abstract classes must contain virtual methods because they rely on the extending classes' implementation. For Example:

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.
    }
}
云仙小弟 2024-10-16 14:49:20

Java 中的所有函数默认都是虚拟的。

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

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

All functions in Java are virtual by default.

You have to go out of your way to write non-virtual functions by adding the "final" keyword.

This is the opposite of the C++/C# default. Class functions are non-virtual by default; you make them so by adding the "virtual" modifier.

追星践月 2024-10-16 14:49:20

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

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

来自 Java 语言规范 v3:

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

  1. C 是 A 的子类。
  2. m1 的签名是签名的子签名(第 8.4.2 节)
    平方米。
  3. 要么
    * m2 是公共的、受保护的或声明为具有默认访问权限
    与 C 相同的包,或者
    * m1 重写了 m3 方法,m3 与 m1 不同,m3 与 m3 不同
    m2,这样 m3 就会覆盖 m2。

All non-private instance methods are virtual by default in Java.

In C++, private methods can be virtual. This can be exploited for the non-virtual-interface (NVI) idiom. In Java, you'd need to make the NVI overridable methods protected.

From the Java Language Specification, v3:

8.4.8.1 Overriding (by Instance Methods) An instance method m1
declared in a class C overrides
another instance method, m2, declared
in class A iff all of the following
are true:

  1. C is a subclass of A.
  2. The signature of m1 is a subsignature (§8.4.2) of the signature
    of m2.
  3. Either
    * m2 is public, protected or declared with default access in the
    same package as C, or
    * m1 overrides a method m3, m3 distinct from m1, m3 distinct from
    m2, such that m3 overrides m2.
阪姬 2024-10-16 14:49:20

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

Yes, you can write virtual "functions" in Java.

与酒说心事 2024-10-16 14:49:20

在Java中,所有公共(非私有)变量&默认情况下,函数是虚拟
此外变量&使用关键字final的函数不是虚拟

In Java, all public (non-private) variables & functions are Virtual by default.
Moreover variables & functions using keyword final are not virtual.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文