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

2022-09-02 09:31:57

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

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


答案 1

虚函数在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.
    }
}

是的,您可以使用抽象类在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()
    }
}

您可以通过使函数最终确定来强制函数在泛型类中不具有虚拟

例如:

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

答案 2

至少在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();

将打印“B”。

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

编辑:


作为对您的评论的回应,Naveen:

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

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

在C++如果你有虚拟方法并做这样的事情,你会得到不同的行为。

a->sayhi();

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

a.sayhi();

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


推荐