【问题标题】:Instance of derived class calling empty method in base派生类实例调用基类中的空方法
【发布时间】:2017-05-10 12:00:58
【问题描述】:

我有一个基类和派生类,基类有两个在派生类中被覆盖的方法。让我们看下面的场景:

我的基类

public class BaseClass

public Overridable function method1()

method2()
End Function

public Overridable function method2()
' Empty !!!
End Function
End class 

我的派生类

public class DerivedClass

public Overrides function method1()

MyBase.method1()
End Function

public Overrides function method2()

' Some code !!
End Function
End class 

现在我已经创建了派生类的一个实例并调用了method1()。

Dim obj as new DerivedClass()
obj.method1()

method1() 派生调用base 中的method1(),后者调用base 中的method2。对我来说奇怪的是base中的method2,它是空的,在派生中调用了method2! ..

谁能向我解释发生了什么以及如何使用继承调用方法?这个层次结构应用了什么概念?

【问题讨论】:

    标签: vb.net oop


    【解决方案1】:

    method1()在派生调用method1()在base中,在base中调用method2。

    这就是你错的地方。

    由于 method2 是可重写的,因此它是一个“虚拟方法”。因此,对 method2 的所有调用都会调用覆盖的版本。这包括基类的method1中的method2调用:

    Public Class BaseClass
        Public Overridable function method1()
            method2()  ' <-- If method2 has been overridden, the overridden
                       '     version is called here.
        End Function
        ...
    End Class
    

    【讨论】:

    • 您的意思是任何 Empty 可覆盖的方法都是“虚拟方法”?编译器如何知道应该执行被覆盖的方法而不是 Empty 方法?
    • @AreejQadomi:每个可覆盖的方法(不仅仅是空的)都是“虚拟方法”。编译器不知道它。 runtime 知道对象的具体类型是“DerivedClass”,因此必须调用它的 method2 实现。因此,这被称为“运行时多态”。
    【解决方案2】:

    VB 中的可覆盖方法,就像 C# 中的虚拟方法一样,不是直接调用的,而是通常使用所谓的包含方法指针的 vtable。这样,当您有一个 BaseClass 类型的实例时,vtable 将指向可覆盖方法的 BaseClass 版本。当您有 DerivedClass 的实例时,指向其方法版本的指针会覆盖 vtable 中的内容,因此当调用该方法时,它将调用派生类版本。有关 vtable 的更多信息,请参阅this question

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 2019-07-25
      • 1970-01-01
      • 2018-11-03
      • 2014-03-17
      • 2014-09-05
      • 2016-01-01
      • 2016-11-14
      • 2013-02-12
      相关资源
      最近更新 更多