虚拟函数在 C# 和 Java 中如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/460446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:15:53  来源:igfitidea点击:

How do virtual functions work in C# and Java?

c#javavirtualvtable

提问by Naveen

How do the virtual functions work in C# and Java?

虚拟函数在 C# 和 Java 中是如何工作的?

Does it use same vtable and vpointer concept similar to C++ or is it something totally different?

它使用与 C++ 相似的相同 vtable 和 vpointer 概念还是完全不同的东西?

回答by Miserable Variable

I am sure Java does not use vtables, since it is able to support binary compatibility.

我确信 Java 不使用 vtables,因为它能够支持二进制兼容性。

To Clarify: The vtable is built when the derived/sub class is compiled. If the base/super class layout changes then the vtable for the d/s needs to be recompiled. In Java this is not the case. You can change the b/s without having to recompile the d/s.

澄清:在编译派生/子类时构建 vtable。如果基类/超类布局发生变化,则需要重新编译 d/s 的 vtable。在 Java 中,情况并非如此。您可以更改 b/s 而无需重新编译 d/s。

Hmmm. It is possible that a vtable is built at runt-time. when the class is loaded. In which case Java and C++ would be same same but different.

嗯。vtable 可能是在运行时构建的。当类加载时。在这种情况下,Java 和 C++ 将相同但不同。

回答by patros

There is no virtual keyword in Java at least.

至少在 Java 中没有 virtual 关键字。

It just resolves to the most derived version of whatever method you're calling...

它只是解析为您正在调用的任何方法的最派生版本......

class A{
void sayhi(){ System.out.println("A");}
}
class B extends A{
void sayhi(){ System.out.println("B");}
}

A a = new B();
a.sayhi();

Will print "B".

将打印“B”。

You can create "pure virtual" methods by declaring a class Abstract and leaving the pure virtual methods declared but unimplemented. Or by using interface / implements instead of class / extends. An interface is basically a class where all of the methods are pure virtual. This has the added bonus that a class can implement multiple interfaces, since unlike C++ a Java class can only inherit one other class directly.

您可以通过声明一个 Abstract 类并保留声明但未实现的纯虚拟方法来创建“纯虚拟”方法。或者通过使用接口/实现而不是类/扩展。接口基本上是一个类,其中所有方法都是纯虚拟的。这有一个额外的好处,即一个类可以实现多个接口,因为与 C++ 不同,Java 类只能直接继承另一个类。

EDIT:

编辑:



In response to your comment, Naveen:

针对您的评论,Naveen:

If you said A a = new A(); a.sayhi(); it would print "A".

如果你说 A a = new A(); a.sayhi(); 它会打印“A”。

The java terminology is dynamic. You can think of it as virtual, but that may confuse some Java devs. the ones who don't know C++, at least. In Java there are no explicit pointers, so we don't need to worry about virtual / non virtual. There are no VTables, you just backtrack the class and its ancestors until you find an implementation of the method you want. There's only single inheritance, so you don't have to worry about order of constructors (it's always bottom up).

Java 术语是动态的。您可以将其视为虚拟的,但这可能会使一些 Java 开发人员感到困惑。至少那些不知道 C++ 的人。在 Java 中没有显式指针,所以我们不需要担心虚拟/非虚拟。没有 VTable,您只需回溯该类及其祖先,直到找到所需方法的实现。只有单一继承,因此您不必担心构造函数的顺序(它总是自下而上)。

In C++ you get different behaviour if you have virtual methods and do something like

在 C++ 中,如果您有虚拟方法并执行类似的操作,您会得到不同的行为

a->sayhi();

where a was A* pointing to an instance of B instead of

其中 a 是 A* 指向 B 的一个实例而不是

a.sayhi();

where a was an object of type A holding an object of type B

其中 a 是类型 A 的对象,持有类型 B 的对象

回答by patros

All languages supporting polymorphism use vtables to resolve method calls to the correct function. So also Java and .NET.

所有支持多态的语言都使用 vtables 来解析对正确函数的方法调用。Java 和 .NET 也是如此。

They both compile to some intermediate langauge (IL for .NET and byte code for java) but the vtable is not visible in this intermediate language. It is supported by the underlying engine (CLR for .NET)

它们都编译为一些中间语言(.NET 的 IL 和 Java 的字节码),但 vtable 在这种中间语言中不可见。它由底层引擎支持(CLR for .NET)

回答by patros

Pure virtual functions are in C++. C# uses Interfaces to serve the same purpose, so I'd suggest you go that route.

纯虚函数在 C++ 中。C# 使用接口来达到同样的目的,所以我建议你走那条路。

回答by Anshul Shukla

In Java virtual function is totally different. In Java, virtual function means a function which can be overridden in its subclasses. So all non-static methods of Java are virtual function. Only the final and private function are not inherited so they are not virtual function.

在 Java 中,虚函数是完全不同的。在 Java 中,虚函数是指可以在其子类中覆盖的函数。所以Java的所有非静态方法都是虚函数。只有 final 和 private 函数没有被继承,所以它们不是虚函数。

So we can say that all non-static function which are not final and private are virtual function in Java.

所以我们可以说所有非 final 和 private 的非静态函数在 Java 中都是虚函数。

回答by Eric Leschinski

How do virtual functions work in Java?

Java 中的虚函数是如何工作的?

Coding interviewers love this question. Yes. Although Java does NOT have a virtual keyword, Java has virtual functions and you can write them.

编码面试官喜欢这个问题。是的。尽管 Java 没有 virtual 关键字,但 Java 有虚拟函数,您可以编写它们。

In object-oriented programming, a virtual functionor virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature. This concept is a very important part of the polymorphism portion of object-oriented programming (OOP).

在面向对象的编程中,虚函数或虚方法是一个函数或方法,其行为可以在继承类中被具有相同签名的函数覆盖。这个概念是面向对象编程 (OOP) 多态性部分的一个非常重要的部分。

Asking an architecture question about a specific language like this requires great communication skills and a deep mastery of underlying principles of the Java compiler, specifically interfaces, abstract classes, and how inheritance works.

像这样询问关于特定语言的架构问题需要很好的沟通技巧和对 Java 编译器的基本原理的深入掌握,特别是接口、抽象类以及继承的工作原理。

Guide the interviewer onto a specific example of a virtual function.

将面试官引导至虚拟功能的特定示例。

Yes you can write virtual functions in Java with interfaces.

是的,您可以使用接口在 Java 中编写虚拟函数。

Java interface methodsare all "pure virtual" because they are designed to be overridden. For example:

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 implementing applyBrakes()
       System.out.println("Brakes applied"); //function, proving it is virtual.
    }
}

Yes you can write virtual functions in Java with abstract classes.

是的,您可以使用抽象类在 Java 中编写虚拟函数。

Java Abstract classescontain implicitly "virtual" methods, implemented by classes extending it. For Example:

Java抽象类包含隐式“虚拟”方法,由扩展它的类实现。例如:

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 virtual function because it
}                                     //is part of an abstract class and isn't
                                      //final.  
class MyDog extends Dog{
    void jump(){
        System.out.println("boing");    //here jump() is being overridden, a 
    }                                   //demonstration that it is virtual.
}
public class Runner {
    public static void main(String[] args) {
        MyDog myDog = new MyDog();       //instantiating myDog
        myDog.jump();                    //calling the overridden function jump()
    }
}

You can force a function to NOT be virtual in a generic class by making it final

你可以强制一个函数在泛型类中不是虚拟的 final

For example:

例如:

class myJavaFoobarClass {

    final boolean giveMeTrueFunction()   //this Java function is NOT virtual
    {                                    //because final keyword prevents this
        return true;                     //function from being modified in a
    }                                    //subclass.

    boolean isItRainingFunction()   //this Java function IS virtual because
    {                               //without the final keyword, the function
        return false;               //can be overridden in a subclass.
    }
}