Reputation: 1975
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?
Upvotes: 7
Views: 36695
Reputation: 61262
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
Upvotes: 13
Reputation: 1219
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 within the dog
class, and that you can then expose it with a different name. But what about using a conditional?
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 getTheAnimalInTheDog
and make it 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 ;)
Upvotes: 0
Reputation: 3326
I think if you drop "Overridable" and change "Overrides" to "New" you'll get what you want.
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"
Upvotes: 0
Reputation: 37880
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.
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 Speak function 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.
Upvotes: 0
Reputation: 18397
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
MyBase.Speak()
which would invoke the parent class' implementation, but from outside the Dog class there's no way to do it.
Upvotes: 1