method how c# inheritance override

how - sealed c#



Ayuda con AnulaciĆ³n y Herencia (8)

Ok, tengan paciencia conmigo chicos y chicas mientras estoy aprendiendo. Aquí está mi pregunta

No puedo entender por qué no puedo anular un método de una clase para padres. Aquí está el código de la clase base (sí, robé el código java de un libro OOP y estoy tratando de reescribirlo en C #).

using System; public class MoodyObject { protected String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } }

y aquí están mis otros 2 objetos que heredan la clase base (MoodyObject):

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class SadObject: MoodyObject { protected String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } }

Y:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class HappyObject: MoodyObject { protected String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } }

y aquí está mi principal:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MoodyObject moodyObject = new MoodyObject(); SadObject sadObject = new SadObject(); HappyObject happyObject = new HappyObject(); Console.WriteLine("How does the moody object feel today?"); moodyObject.queryMood(); Console.WriteLine(""); Console.WriteLine("How does the sad object feel today?"); sadObject.queryMood(); sadObject.cry(); Console.WriteLine(""); Console.WriteLine("How does the happy object feel today?"); happyObject.queryMood(); happyObject.laugh(); } } }

Como puede ver, algo bastante básico, pero aquí está la salida:

¿Cómo se siente hoy el objeto caprichoso? ¡Me siento malhumorado hoy!

¿Cómo se siente el objeto triste hoy? ¡Me siento malhumorado hoy! wah ... boohoo

¿Cómo se siente el objeto feliz hoy? ¡Me siento malhumorado hoy! hehehehehehe Pulse cualquier tecla para continuar . . .

No como esperaba Intenté hacer que el método base sea virtual y anular las llamadas cuando intento anularlo y eso me da el error "no puede anular el miembro heredado ''MoodyObject.getMood ()'' porque no está marcado como virtual, abstracto o sobrescrito". También lo intenté sin lo virtual y anulé y creo que estoy tratando de ocultar el método base. De nuevo, soy nuevo en OOP y agradecería cualquier orientación.

EDITADO PARA AGREGAR: ¡Lo encontré! MoodyObject.cs era solo un "elemento de solución" en el explorador de soluciones en comparación con un elemento "ConsoleApplication1". Lo arrastré hasta donde pertenecía en el explorador de soluciones y ¡voilá! Ahora funciona. Marqué la respuesta de Luc a continuación como la respuesta porque me ofreció la ayuda que necesitaba para llegar a donde la resolví ... Estoy aprendiendo mucho aquí. ¡Es increíble y ustedes y las chicas son locos inteligentes!


Al hacer que su método GetMood sea virtual en Moody y override en las clases derivadas, su código debería funcionar. ¿Estás seguro de haber colocado estas palabras clave en el lugar al que pertenecen? Aquí está el código completo, que compila y funciona bien:

public class MoodyObject { protected virtual String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } public class SadObject : MoodyObject { protected override String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } public class HappyObject : MoodyObject { protected override String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } class Program { static void Main(string[] args) { MoodyObject moodyObject = new MoodyObject(); SadObject sadObject = new SadObject(); HappyObject happyObject = new HappyObject(); Console.WriteLine("How does the moody object feel today?"); moodyObject.queryMood(); Console.WriteLine(""); Console.WriteLine("How does the sad object feel today?"); sadObject.queryMood(); sadObject.cry(); Console.WriteLine(""); Console.WriteLine("How does the happy object feel today?"); happyObject.queryMood(); happyObject.laugh(); Console.Read(); } }

Tal vez su error proviene del hecho de que en Java, todos los métodos son virtuales, que no es el caso es C # (como lo señaló Dan C.).


Debe marcar las anulaciones de getMood con la palabra clave "anular". También deberá marcar el método base getMood con la palabra clave "virtual".


Debe utilizar la palabra clave de anulación para anular cualquier virtual o implementar cualquier método abstracto.

public class MoodyObject { protected virtual String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } public class HappyObject : MoodyObject { protected override string getMood() { return "happy"; } }

Lo que recomendaría aquí es que probaste que MoodyObject sea una clase abstracta. (Tendría que cambiar su método principal si hace esto, pero debería explorarlo). ¿Realmente tiene sentido estar en un modo temperamental? El problema con lo que tenemos arriba es que su HappyObject no está obligado a proporcionar una implementación para getMood. Al hacer un resumen de clase, hace varias cosas:

  1. No puede actualizar una instancia de una clase abstracta. Tienes que usar una clase infantil.
  2. Puede obligar a los niños derivados a implementar ciertos métodos.

Entonces para hacer esto terminas:

public abstract class MoodyObject { protected abstract String getMood(); public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } }

Tenga en cuenta que ya no proporciona una implementación para getMood.


En C #, los métodos no son virtuales por defecto, por lo que si diseña algún método como reemplazable, debe especificarlo como virtual:

class Base { protected virtual string GetMood() {...} }

En segundo lugar, debe especificar que va a anular el método de la clase base en la clase derivada.

class Derived : Base { protected override string GetMood() {...} }

Si no especifica la palabra clave "anular", obtendrá el método que oculta el tipo de base (y la advertencia del compilador para poner la palabra clave "nueva" para que el método lo indique explícitamente).

Si desea detener la cadena de herencia y no permitir otras anulaciones del método, debe marcar el método como sellado, como este:

protected sealed override string GetMood() {...}



Por lo que sé, en Java todos los métodos son virtuales por defecto. Este no es el caso con C #, por lo que debe marcar los métodos de la clase base con "virtual", por ejemplo, protected virtual string getMood() ... y las sustituciones con "anular", por ejemplo, la protected override string getMood()... .


Si desea anular un método de clase base, debe declararse como virtual . El método de anulación en una clase derivada debe declararse explícitamente como override . Esto debería funcionar:

public class BaseObject { protected virtual String getMood() { return "Base mood"; } //... } public class DerivedObject: BaseObject { protected override String getMood() { return "Derived mood"; } //... }

Editar: Acabo de probarlo en la aplicación de consola ac #, y se compila. Por lo tanto, el código fuente que use debe diferir en alguna pieza pequeña pero importante de lo que publicó aquí.

Mi program.cs es esto:

using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // leaving out your implementation to save space... } } public class SadObject : MoodyObject { protected override String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } public class HappyObject : MoodyObject { protected override String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } }


public class SadObject: MoodyObject { override String getMood()