2012-10-04 58 views
6

Supongamos que tengo una clase principal abstracta llamada "Principal" que implementa un método llamado "Mostrar título". Quiero que este método sea el mismo para cada subclase que herede "Parent": me gustaría un error de compilación si una subclase intenta implementar su propio método "DisplayTitle". ¿Cómo puedo lograr esto en C#. Creo en Java, simplemente marcaría el método como "final", pero parece que no puedo encontrar una alternativa en C#. He estado jugando con "sellado" y "anular", pero no puedo obtener el comportamiento que estoy buscando.Evitar que una subclase de C# sobrescriba un método

Por ejemplo, en este código:

using System; 

namespace ConsoleApplication1 
{ 
    class Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Parent's Title"); } 
    } 

    class ChildSubclass : Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title"); 
    } 

    static void Main(string[] args) 
    { 
     ChildSubclass myChild = new ChildSubclass(); 
     myChild.DisplayTitle(); 
     Console.ReadLine(); 
    } 
    } 
} 

Me gustaría recibir un error de compilación diciendo que el "ChildSubClass" no puede anular "DISPLAYTITLE". Actualmente recibo una advertencia, pero parece que esto es algo que debería poder hacer y no conozco los atributos adecuados para etiquetar el método.

Respuesta

10

¿Cómo puedo lograr esto en C#. Creo en Java, simplemente marcaría el método como "final", pero parece que no puedo encontrar una alternativa en C#.

El equivalente aproximado es sealed en C#, pero normalmente sólo se necesitan métodos virtuales - y su método de DisplayTitle no es virtual.

Es importante señalar que no es ChildSubclass anulando DisplayTitle - es ocultar ella. Cualquier código que solo use referencias a Parent no terminará llamando a esa implementación.

Tenga en cuenta que con el código que está, usted debe obtener una advertencia de tiempo de compilación para avisarle que añadir el modificador new con el método del ChildSubclass:

public new void DisplayTitle() { ... } 

no se puede parada clases derivadas ocultar los métodos existentes, salvo sellar la clase en sí para evitar la creación de una clase derivada por completo ... pero a las personas que llaman que no usan el tipo derivado directamente no les importará.

¿Cuál es su real preocupación aquí? Mal uso accidental, o problemas deliberados?

EDIT: Tenga en cuenta que la advertencia para el código de ejemplo sería algo así como:

Test.cs(12,19): warning CS0108: 
     'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited 
     member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword 
     if hiding was intended. 

Sugiero que encienda advertencias en errores, y luego es más difícil hacer caso omiso de ellos :)

+1

Supongo que mi verdadera preocupación sería el uso indebido accidental. Tengo una clase abstracta en otro proyecto que tiene un método "TurnOn" y "TurnOff". Sin entrar demasiado en los detalles, esta clase va a ser subclases varias veces para representar objetos del mundo real. Sin embargo, todos estos dispositivos se encenderán y apagarán de la misma manera. Simplemente no quiero que yo mismo u otra persona intente implementar sus propios comandos de apagado/encendido para dispositivos individuales sin una advertencia de algún tipo. – user1720817

+0

@ user1720817: Bueno, habría * ser * una advertencia. Editaré la advertencia de su código de muestra en mi respuesta ... –

+0

Sí, hay una advertencia :) Es solo mi OCD que me hace querer que sea un error de tiempo de compilación. Gracias por tomarse el tiempo para escribir esto! – user1720817

1

Utilice el modificador sellado para evitar que las subclases anulen sus clases, propiedades o métodos. ¿Qué no funciona cuando usas sellado?

http://msdn.microsoft.com/en-us/library/88c54tsw.aspx

+0

Cuando uso: "public sealed void DisplayTitle() {Console.WriteLine (" Parent's Title ");}" Aparece un error de compilación - "'ConsoleApplication1.Parent.DisplayTitle()' no se puede sellar porque no es una anulación ". – user1720817

2

Una clase derivada no puede anular su método, usted no lo declaró virtual. Tenga en cuenta que eso es muy diferente en C# comparado con Java, todos los métodos son virtuales en Java. En C# debe usar explícitamente la palabra clave.

Una clase derivada puede ocultar su método utilizando nuevamente el mismo nombre. Esta es probablemente la advertencia de compilación de la que está hablando. El uso de la nueva palabra clave suprime la advertencia. Este método no anula de ninguna manera su método original, su código de clase base siempre llama al método original, no al de la clase derivada.

+0

+1, especialmente para C#/diferencia de Java. –

0

Estoy bastante seguro de que lo que desea no es posible en C# utilizando las palabras clave modificadoras del método.

sellado sólo se aplica cuando anulando un método virtual en una clase de antepasado, que luego prevenir más primordial.

+0

Buen punto, pero el OP quiere evitar ocultar el método base al heredar clases. Simplemente no es posible. –

+0

Supongo que esto parece ser parte de lo que más me confunde: ¿por qué puedo sellar un método heredado, pero no puedo hacerlo en la clase "base"? – user1720817

+0

@MichaelSallmen, dije "lo que quieres no es posible", ¿dónde está tu confusión? – Jace

Cuestiones relacionadas