Pregunta

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 primaria. Aquí está el código de la clase base (sí, robé el código de Java de un libro de 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, cosas bastante básicas, pero aquí está el resultado:

  

¿Cómo se siente el objeto cambiante hoy?   ¡Me siento de mal humor hoy!

     

¿Cómo se siente el objeto triste hoy? yo   sentirse mal de hoy! wah ... boohoo

     

¿Cómo se siente el objeto feliz hoy?   ¡Me siento de mal humor hoy! jejejejejejeje.   Pulse cualquier tecla para continuar . . .

No como esperaba. Intenté hacer que el método base sea virtual y llamar a la anulación al intentar anularlo y eso solo me da este error '' no puede anular el miembro heredado 'MoodyObject.getMood ()' porque no está marcado virtual, abstracto o anular ''. . También lo probé sin la anulación virtual y cree que estoy tratando de ocultar el método base. Nuevamente, 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 lugar de una " ConsoleApplication1 " ít. Lo arrastré hasta donde pertenecía al explorador de soluciones y ¡listo! Ahora funciona. Marqué la respuesta de Luc a continuación como la respuesta porque me ofreció la ayuda que necesitaba para llegar a donde lo resolví ... Estoy aprendiendo mucho aquí. ¡Es increíble y ustedes, chicos y chicas, son muy inteligentes!

¿Fue útil?

Solución

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

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

Segundo, 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 " anular " palabra clave, obtendrá un método que oculta el tipo base (y una advertencia del compilador para poner " nueva " palabra clave para que el método lo indique explícitamente).

Si desea detener la cadena de herencia y no permitir más anulaciones del método, debe marcar el método como sellado, así:

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

Otros consejos

Debe usar 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 probablemente quisiste decir que MoodyObject es una clase abstracta. (Tendrías que cambiar tu método principal si haces esto, pero debes explorarlo) ¿Realmente tiene sentido estar en un modo cambiante? 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 renovar una instancia de una clase abstracta. Tienes que usar una clase secundaria.
  2. Puede forzar a los hijos 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.

Hasta donde yo 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", p. cadena virtual protegida getMood () ... y las anulaciones con " override " ;, p. cadena de anulación protegida 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 una aplicación de consola C # 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 este:

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.");
        }
    }
}

Necesita decirle a C # que su objeto está anulando la función de la clase base.

Aquí está el artículo de MSDN sobre la sintaxis que necesita: http://msdn.microsoft.com/en-us/library/ebca9ah3 (VS.71) .aspx

public class SadObject: MoodyObject    
{        
    override String getMood()

Al hacer su método GetMood virtual en Moody y override en las clases derivadas, su código debería funcionar. ¿Está seguro de haber colocado estas palabras clave donde pertenecen? Aquí está el código completo, que se compila y se ejecuta 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.).

public class SadObject: MoodyObject
    {
        override String getMood()

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top