2008-10-28 23 views
7

Considere el siguiente código:método de clase base llamada instancia secundaria que fue anulada

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

¿Cómo puedo convertir/ctype la instancia del perro de animal y tienen Animal.Speak ser llamado?

Respuesta

10

No; el método de la subclase anula el método de la superclase, por definición de herencia.

Si desea que el método reemplazado esté disponible, exhíbalo en la subclase, p.

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

No creo que puedas.

Lo que pasa es que el objeto sigue siendo un perro. el comportamiento que describes (obtener "ruff" del objeto lanzado en lugar de "hola") es estándar porque quieres poder utilizar la clase de animal para permitir que hablen un montón de diferentes tipos de animales.

Por ejemplo, si has tenido una tercera clase como sigue:

Public Class Cat 
    Inherits Animal 

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

entonces sería capaz de acceder a ellos como así:

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 

Lo que estamos hablando de hacer básicamente rompe la cadena de herencia. Ahora, esto se puede hacer configurando la función Hable para aceptar un parámetro que le indique que devuelva su valor base o no, o una función SPEAK separada para el valor base, pero listo, no se va para obtener cosas que se comporten de esta manera.

+0

"Otra alternativa, es declarar el objeto como un animal y, a continuación, echar a un perro cuando se necesita propiedades extendidas de los perros " Esa última parte no es verdad. El tipo declarado de la variable no tiene sentido cuando se trata de cómo una instancia determinada se comporta polimórficamente. –

+0

Eso es cierto, estaba pensando en términos de interfaces. –

1

Preguntaría por qué intentas obtener este tipo de comportamiento. Me parece que el hecho de que necesite invocar la implementación de un método por parte de la clase principal es una indicación de que tiene un defecto de diseño en otro lugar del sistema.

En resumidas cuentas, como otros han declarado que no hay forma de invocar la implementación de la clase para padres dada la forma en que ha estructurado sus clases. Ahora dentro de la clase de perro que se podría llamar

MyBase.Speak() 

lo cual invocará la implementación de la clase padre, pero desde fuera de la clase Perro no hay manera de hacerlo.

1

Creo que si sueltas "Overridable" y cambias "Overrides" a "New" obtendrás lo que quieras.

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

La nueva palabra clave es cómo lo haría en C#. El equivalente en VB es Sombras. En general, es una mala idea usar Shadows. Es una práctica de Diseño Orientada a Objetos pobre. Es una violación del Principio de Sustitución de Liskov. –

0

Sé que esto ha sido publicado hace unos meses, pero todavía voy a tratar de responder, tal vez sólo por el bien de la completitud.

Le han dicho que se puede acceder desde el método sobreescrito dentro de la clase dog, y que a continuación, puede exponerse con un nombre diferente. Pero, ¿qué pasa con el uso de un condicional?

Sólo puede hacer:

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 

y luego llamar a ellos como:

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

Como alternativa, puede getTheAnimalInTheDog y hacer queSpeak():

Sólo puede hacer:

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 

Y luego otra vez:

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

creo que sirve;)

Cuestiones relacionadas