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

Nav*_*een 20 c# java virtual vtable

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

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

Eri*_*ski 21

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

编码采访者喜欢这个问题.是.虽然Java没有虚拟关键字,但Java具有虚函数,您可以编写它们.

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

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

引导访谈者了解虚拟功能的具体示例.

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

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.
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过创建函数来强制函数在泛型类中不是虚拟的 final

例如:

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.
    }
}
Run Code Online (Sandbox Code Playgroud)


pat*_*ros 10

Java中至少没有虚拟关键字.

它只是解析为你所调用的任何方法的派生版本...

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

A a = new B();
a.sayhi();
Run Code Online (Sandbox Code Playgroud)

将打印"B".

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

编辑:


在回答你的评论时,Naveen:

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

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

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

a->sayhi();
Run Code Online (Sandbox Code Playgroud)

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

a.sayhi();
Run Code Online (Sandbox Code Playgroud)

其中a是A类型的对象,其中包含B类对象


Mis*_*ble 0

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

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

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