vb.net 从子实例调用被覆盖的基类方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/244886/
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-09-09 13:53:28  来源:igfitidea点击:

From Child instance call base class method that was overridden

vb.netinheritance

提问by MattH

Consider the following code:

考虑以下代码:

Public Class Animal

Public Overridable Function Speak() As String
    Return "Hello"
End Function

End Class

Public Class Dog
    Inherits Animal

    Public Overrides Function Speak() As String
        Return "Ruff"
    End Function

End Class

Dim dog As New Dog
Dim animal As Animal
animal = CType(dog, Animal)
// Want "Hello", getting "Ruff"
animal.Speak()

How can I convert/ctype the instance of Dog to Animal and have Animal.Speak get called?

如何将 Dog 的实例转换/ctype 为 Animal 并调用 Animal.Speak?

回答by Steven A. Lowe

You don't; the subclass's method overrides the superclass's method, by definition of inheritance.

你没有;根据继承的定义,子类的方法覆盖超类的方法。

If you want the overridden method to be available, expose it in the subclass, e.g.

如果您希望覆盖的方法可用,请在子类中公开它,例如

Public Class Dog 
    Inherits Animal
    Public Overrides Function Speak() As String
        Return "Ruff"
    End Function
    Public Function SpeakAsAnimal() As String
        Return MyBase.Speak()
    End Function
End Class

回答by Mike Deck

I would ask why you are trying to get this type of behavior. It seems to me that the fact you need to invoke the parent class' implementation of a method is an indication that you have a design flaw somewhere else in the system.

我会问你为什么要尝试这种行为。在我看来,您需要调用父类的方法实现这一事实表明您在系统的其他地方存在设计缺陷。

Bottom line though, as others have stated there is no way to invoke the parent class' implementation given the way you've structured your classes. Now within the Dog class you could call

但最重要的是,正如其他人所说,鉴于您构建类的方式,无法调用父类的实现。现在在 Dog 类中,您可以调用

MyBase.Speak()

which would invoke the parent class' implementation, but from outside the Dog class there's no way to do it.

这将调用父类的实现,但从 Dog 类之外没有办法做到这一点。

回答by Matt Burke

I think if you drop "Overridable" and change "Overrides" to "New" you'll get what you want.

我认为如果您删除“Overridable”并将“Overrides”更改为“New”,您将得到您想要的。

Public Class Animal

Public Function Speak() As String
    Return "Hello"
End Function

End Class

Public Class Dog
    Inherits Animal

    Public New Function Speak() As String
        Return "Ruff"
    End Function

End Class

Dim dog As New Dog
Dim animal As Animal
dog.Speak() ' should be "Ruff"
animal = CType(dog, Animal)
animal.Speak() ' should be "Hello"

回答by tfrascaroli

I know this has been posted a few months back, but I'm still going to try and reply, maybe just for the sake of completeness.

我知道这已经在几个月前发布了,但我仍然会尝试回复,也许只是为了完整性。

You've been told that you can access the overriden method from withinthe dogclass, and that you can then expose it with a different name. But what about using a conditional?

你一直在说,你可以从访问覆盖方法dog类,并且您可以再使用不同的名称揭露它。但是使用条件呢?

You can just do:

你可以这样做:

Public Class Animal

Public Overridable Function Speak(Optional ByVal speakNormal as Boolean = False) As String
    Return "Hello"
End Function

End Class

Public Class Dog
    Inherits Animal

    Public Overrides Function Speak(Optional ByVal speakNormal as Boolean = False) As String
        If speakNormal then
            return MyBase.Speak()
        Else
            Return "Ruff"
        End If
    End Function

End Class

And then call them like:

然后像这样调用它们:

Dim dog As New Dog
Dim animal As new Animal
animal.Speak() //"Hello"
dog.Speak()//"Ruff"
dog.Speak(true)//"Hello"

Alternatively, you can getTheAnimalInTheDogand make itSpeak():

或者,你可以getTheAnimalInTheDog和做Speak()

You can just do:

你可以这样做:

Public Class Animal

Public Overridable Function Speak() As String
    Return "Hello"
End Function

Public MustOverride Function GetTheAnimalInMe() As Animal

End Class

Public Class Dog
    Inherits Animal

    Public Overrides Function Speak() As String
        Return "Ruff"
    End Function

    Public Overrides Function GetTheAnimalInMe() As Animal
        Dim a As New Animal
        //Load a with the necessary custom parameters (if any)
        Return a
    End Function
End Class

And then again:

然后再说一遍:

Dim dog As New Dog
Dim animal As new Animal
animal.Speak() //"Hello"
dog.Speak()//"Ruff"
dog.GetTheAnimalInMe().Speak()//"Hello"

Hope it helps ;)

希望能帮助到你 ;)

回答by Stephen Wrighton

I don't think you can.

我不认为你可以。

The thing is that the object is still a dog. the behavior you're describing (getting "ruff" from the casted object rather than "hello") is standard because you want to be able to use the animal class to let a bunch of different type of animals speak.

问题是对象仍然是一只狗。您所描述的行为(从铸造对象中获得“ruff”而不是“hello”)是标准的,因为您希望能够使用动物类让一群不同类型的动物说话。

For example, if you had a third class as thus:

例如,如果你有这样的第三堂课:

Public Class Cat
    Inherits Animal

    Public Overrides Function Speak() As String
        Return "Meow"
    End Function
End Class

Then you'd be able to access them like thus:

然后你就可以像这样访问它们:

protected sub Something
    Dim oCat as New Cat
    Dim oDog as New Dog

    MakeSpeak(oCat)
    MakeSpeak(oDog)
End sub

protected sub MakeSpeak(ani as animal)
    Console.WriteLine(ani.Speak())
end sub 

What you're talking about doing basically breaks the inheritance chain. Now, this can be done, by setting up the Speakfunction to accept a parameter which tells it to return it's base value or not or a separate SPEAK function for the base value, but out of the box, you're not going to get things that behave this way.

你所说的基本上破坏了继承链。现在,这可以通过设置Speak函数来接受一个参数,该参数告诉它是否返回它的基值或一个单独的基值的 SPEAK 函数,但是开箱即用,你不会得到以这种方式行事的事情。