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

发布于 2024-07-11 10:47:55 字数 82 浏览 8 评论 0原文

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

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

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

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

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

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

发布评论

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

评论(6

誰認得朕 2024-07-18 10:47:55

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

编码面试官喜欢这个问题。 是的。 虽然Java没有virtual关键字,但是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()
    }
}

您可以通过将函数设为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.
    }
}

How do virtual functions work in Java?

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

In object-oriented programming, a virtual function or 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).

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.

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

Yes you can write virtual functions in Java with interfaces.

Java interface methods are all "pure virtual" because they are designed to be overridden. 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 implementing applyBrakes()
       System.out.println("Brakes applied"); //function, proving it is virtual.
    }
}

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

Java Abstract classes contain implicitly "virtual" methods, implemented by classes extending it. 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 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

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.
    }
}
北笙凉宸 2024-07-18 10:47:55

至少Java中没有virtual关键字。

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

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”。

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

编辑:


为了回应你的评论,纳文:

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

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

在 C++ 中,如果您有虚拟方法并执行类似

a->sayhi();

a 是 A* 指向 B 实例的操作,而不是

a.sayhi();

a 是持有 B 类型对象的 A 类型对象,则会得到不同的行为

There is no virtual keyword in Java at least.

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

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.

EDIT:


In response to your comment, Naveen:

If you said A a = new A(); a.sayhi(); it would print "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).

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

a->sayhi();

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

a.sayhi();

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

西瑶 2024-07-18 10:47:55

在Java中虚函数是完全不同的。 在Java中,虚函数是指可以在其子类中重写的函数。 所以Java的所有非静态方法都是虚函数。 只有最终函数和私有函数不会被继承,因此它们不是虚函数。

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

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.

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

薄荷港 2024-07-18 10:47:55

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

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

All languages supporting polymorphism use vtables to resolve method calls to the correct function. So also Java and .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)

葬花如无物 2024-07-18 10:47:55

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

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

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

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

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.

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.

不…忘初心 2024-07-18 10:47:55

纯虚函数是 C++ 中的。 C# 使用接口来达到相同的目的,所以我建议您走这条路。

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

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