tengo el siguiente código.
public class Parent { public void Print() { Console.WriteLine ("Parent Method"); } } public class Child : Parent { public new void Print() { Console.WriteLine ("Child Method"); } } public class Program { public static void Main() { Child C = new Child(); C.Print(); } }Si ejecuto este código, obtengo el resultado "Método secundario" Pero si hago lo siguiente, ¿por qué obtengo el resultado "Método principal"?
public class Parent { public void Print() { Console.WriteLine ("Parent Method"); } } public class Child : Parent { public new void Print() { Console.WriteLine ("Child Method"); } } public class Program { public static void Main() { Parent P = new Child(); // The only difference is this. P.Print(); } }La única diferencia es la siguiente
Child C = new Child(); Parent P = new Child(); Pensé que new Child() significa que creamos la instancia de la clase Child . Y pensé que tanto C como P son solo variables de referencia de objetos que contienen la ubicación de la instancia de la clase Child .
¿Pueden corregirme si me equivoco o decirme si me equivoco en algo porque no entiendo por qué en los casos anteriores obtengo resultados diferentes?
Es porque ha vuelto a declarar el método Print en Child . Entonces, en el momento de la compilación, P.Print() se resuelve en Parent.Print , pero C.Print() se resuelve en Child.Print() . Si tuviera un método virtual que se anuló en Child , ambos imprimirían "Método Child":
public class Parent { // Declare this as virtual, allowing it to be overridden in // derived classes. The implementation will depend on the // execution-time type of the object it's called on. public virtual void Print() { Console.WriteLine ("Parent Method"); } } public class Child : Parent { // Override Parent.Print, so if Print is called on a reference // with compile-time type of Parent, but at execution it // refers to a Child, this implementation will be executed. public override void Print() { Console.WriteLine ("Child Method"); } }Relacionada:
override y new ? (Entrada de preguntas frecuentes de C# en MSDN: resultó haber sido escrita por mí, ¡pero lo había olvidado!)override y las new palabras clave (MSDN)Esto es lo que sucede debajo del capó
Child C = new Child(); C.Print();Porque estás ocultando métodos, no anulándolos. por lo tanto, el método Print en Parent está oculto y se invoca Child.Print().
Parent P = new Child(); // The only difference is this. P.Print();Este (New Child()) se llamará en una referencia de tipo principal.
si prueba este, la referencia de tipo principal se convertirá en tipo secundario. De ahora en adelante se invoca a Child.Print().
Parent P = new Child(); ((Child)P).Print();la salida será: Método hijo
Dado que el método Print no es virtual , el compilador no emitirá código para decirle a CLR que invoque el método de acuerdo con el tipo de tiempo de ejecución real.
Entonces, cuando se haga referencia a su variable como Child , se Child.Print . Pero, cuando se refiere a él como Parent , se Parent.Print .
El uso de la new palabra clave aquí solo está destinado a ocultar , para decirle al compilador que el método secundario está ocultando el método principal y no lo anula, pero no tiene ningún efecto.