2008-10-28 4 views
7

Betrachten Sie den folgenden Code überschrieben wurde:Von Child Instanz Aufruf Basisklasse Methode, die

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() 

Wie kann ich konvertieren/die Instanz von Hund zu Tier ctype und haben Animal.Speak genannt werden?

Antwort

10

Sie dies nicht tun; Die Methode der Unterklasse überschreibt die Methode der Oberklasse durch Definition der Vererbung.

Wenn Sie wollen, dass die überschriebene Methode zur Verfügung steht, ist es in der Unterklasse aussetzen, z.B.

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 
0

Ich glaube nicht, dass Sie können.

Die Sache ist, dass das Objekt noch ein Hund ist. das Verhalten Sie beschreiben („ruff“ aus dem gegossenen Objekt immer statt „Hallo“) ist Standard, weil Sie das Tier-Klasse verwenden zu lassen, eine Reihe von verschiedenen Typs in der Lage sein wollen, von Tieren sprechen.

Zum Beispiel, wenn Sie hatte eine dritte Klasse, die als so:

Public Class Cat 
    Inherits Animal 

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

Dann würden Sie in der Lage sein, auf sie zuzugreifen, wie so:

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 

Was Sie sprechen im Grunde tun bricht die Vererbungskette. Nun kann dies geschehen, durch die Einrichtung der Funktion Speak einen Parameter zu übernehmen, die es es Wert Basis oder nicht, oder eine separater SPEAK Funktion für den Grundwert zurück erzählt, aber aus dem Kasten heraus, ich bin nicht los um Dinge zu bekommen, die sich so verhalten.

+0

„Eine weitere Alternative ist das Objekt als ein Tier, zu erklären, und es dann zu einem Hund werfen, wenn Sie den Hund erweiterte Eigenschaften benötigen . " Dieser letzte Teil ist nicht wahr. Der deklarierte Typ der Variablen ist bedeutungslos, wenn es darum geht, wie sich eine gegebene Instanz polymorph verhält. –

+0

Das stimmt, ich habe in Bezug auf Schnittstellen gedacht. –

1

Ich würde fragen, warum Sie diese Art von Verhalten zu bekommen versuchen. Es scheint mir, dass die Tatsache, dass Sie die Implementierung einer Methode durch die Elternklasse aufrufen müssen, ein Hinweis darauf ist, dass Sie einen Designfehler an einer anderen Stelle im System haben. obwohl

Unterm Strich, wie andere schon berichtet haben, gibt es keine Möglichkeit, die Elternklasse Implementierung so, wie Sie strukturiert haben Ihre Klassen gegeben aufzurufen. Jetzt in der Dog-Klasse konnte man

MyBase.Speak() 

nennen, die die Elternklasse Implementierung aufrufen würde, aber von außerhalb der Dog-Klasse gibt es keine Möglichkeit, es zu tun.

1

Ich denke, wenn Sie „Overridable“ und ändern „Überschreibungen“ auf „Neu“ fallen werden Sie bekommen, was Sie wollen.

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" 
+2

Das New-Schlüsselwort ist, wie Sie es in C# tun würden. Das Äquivalent in VB ist Schatten. Es ist generell eine schlechte Idee, Schatten zu benutzen. Es ist eine schlechte objektorientierte Design-Praxis. Es ist ein Verstoß gegen das Liskow-Substitutionsprinzip. –

0

Ich weiß, dass dies vor ein paar Monaten gepostet wurde, aber ich werde immer noch versuchen und zu antworten, vielleicht nur der Vollständigkeit halber.

Ihnen wurde gesagt, dass Sie auf die Methode overriden von innerhalb der Klasse dog zugreifen können, und dass Sie es dann mit einem anderen Namen verfügbar machen können. Aber was ist mit einem bedingten?

Sie können einfach tun:

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 

Und sie dann nennen mag:

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

Alternativ können Sie getTheAnimalInTheDog und machen esSpeak():

Sie können einfach tun:

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 

Und dann wieder:

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

Hoffe, es hilft;)