2008-10-28 3 views
7

Рассмотрим следующий код:От детского метода базового экземпляра вызова класса, который был переопределен

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

Как я могу преобразовать/CTYPE экземпляр Dog в животных и имеют Animal.Speak дозвонились?

ответ

10

У вас нет; метод подкласса переопределяет метод суперкласса, по определению наследования.

Если вы хотите, чтобы переопределенный метод был доступен, выставляйте его в подкласс, например.

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

Я не думаю, что вы можете.

Дело в том, что объект по-прежнему является собакой. поведение, которое вы описываете (получение «ерша» из заклинаемого объекта, а не «привет») является стандартным, потому что вы хотите иметь возможность использовать класс животных, чтобы говорить кучу разных типов животных.

Например, если у вас есть третий класс, как таким образом:

Public Class Cat 
    Inherits Animal 

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

Тогда вы сможете получить доступ к ним, как таким образом:

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 

Что вы говорите делать в основном нарушает цепочку наследования. Теперь это можно сделать, установив функцию Speak, чтобы принять параметр, который говорит ему вернуть его базовое значение или нет или отдельную функцию SPEAK для базового значения, но из коробки вы не собираетесь чтобы получить то, что ведет себя таким образом.

+0

«Другая альтернативе, чтобы объявить объект как животное, а затем бросить его на собаку, когда вам нужно расширенные свойства собаки «. Эта последняя часть неверна. Объявленный тип переменной бессмыслен, когда дело доходит до того, как данный экземпляр ведет себя полиморфно. – 2008-10-28 21:56:00

+0

Это правда, я думал с точки зрения интерфейсов. – 2008-10-29 02:22:55

1

Я бы спросил, почему вы пытаетесь получить такой тип поведения. Мне кажется, что тот факт, что вам нужно вызвать реализацию родительского класса, является признаком того, что у вас есть дефект дизайна где-то еще в системе.

Нижняя строка, хотя другие заявили, что не существует способа вызвать реализацию родительского класса, учитывая то, как вы структурировали свои классы. Теперь в классе собак можно назвать

MyBase.Speak() 

, который будет ссылаться на реализацию родительского класса, но из-за пределов класса собаки нет никакого способа сделать это.

1

Я думаю, что если вы сбросите «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" 
0

Я знаю, что это было опубликовано несколько месяцев назад, но я все равно попытаюсь ответить, может быть, только ради полноты.

Вам сообщили, что вы можете получить доступ к методу overriden от в пределах класса dog, и затем вы можете выставить его с другим именем. Но как насчет использования условного?

Вы можете просто сделать:

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 

А потом называть их люблю:

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

В качестве альтернативы, вы можете getTheAnimalInTheDog и сделать этоSpeak():

Вы можете просто сделать:

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 

А потом опять:

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

Надеется, что это помогает;)

Смежные вопросы