2009-08-25 16 views
5

Tener algo como esto esto:¿Cómo implementar una clase base con un método y aún forzar a la clase derivada a anularla?

public abstract class AAA 
{ 
    protected abstract virtual string ToString() // Error 
    { 
    // Base Stuff 
    } 
} 

public abstract class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString(); 
    // More Stuff 
    } 
} 

leí otro post (abstract method in a virtual class) bruja era bastante como mi pregunta, pero hay una pequeña diferencia. Me gustaría que AAA.ToString() tenga un comportamiento base y fuerce la clase derivada para anularla.

Sé que podría hacer algo como esto (desplazarse hacia abajo) pero estaba buscando una manera adecuada.

public abstract class AAA 
{ 
    public abstract string ToString(); 
    protected string ToString2() 
    { 
    // Base Stuff 
    } 
} 

public class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString2(); 
    // More Stuff 
    } 
} 

Podría también, probablemente, hacer una interfaz de IAAA y construir mi clase de acreditación como

public class BBB : AAA, IAAA { ... } 

pero no me parece correcto.

Respuesta

5

Su enfoque es esencialmente la forma correcta ...

Editar:

Su "Concepto" es:

  1. comportamiento predeterminado
  2. anulación Requerido

Ahora, desde su aplicación oreja a quiere que el "comportamiento por defecto" para siempre ser ejecutado, necesita

public string ToString() 
{ 
    // placeholder for some default behaviour 

    string result = doToString(); 

    // placeholder for some more default behaviour 

    return result; 
} 

protected abstract string doToString(); 

Esto sólo funciona si usted sabe cuál es la clase base está haciendo en general, y desea proporcionar la implementación de doToString() en la clase derivada. Esto se conoce como el patrón de diseño Template Method.

Sin embargo, si usted está buscando una manera de requieren el implementador de una clase derivada de llamar base.ToString() en el cumplimiento de ToString(), entonces no hay manera de hacer esto. Al permitir una anulación, le da el control de clase derivado sobre su implementación.

Puede documentar su recomendación para llamar siempre al base.ToString(), pero eso es todo.

El uso de una interfaz define el contrato público para su clase. Esto no le proporciona ningún beneficio adicional sobre el patrón de Método de plantilla, ya que todavía necesita derivar de una clase base para obtener la implementación "predeterminada".

¿Tiene algún detalle sobre lo que intenta proporcionar en su clase base como el "comportamiento predeterminado"? Tal vez eso ayude a llegar a una mejor solución. Mirando la pregunta referida, este es esencialmente el mismo enfoque.

+0

Gracias, tu edición hizo darme cuenta de algo importante! Incluso si encontrara una forma milagrosa de definir ToString() en la clase base y forzar la anulación en la clase derivada, simplemente no hay manera de forzar la anulación para usar ToString()! También encontré esta publicación de un MVP sobre forzar la anulación: http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/c25b6477-b990-4284-abaf-801ddf18207c. Gracias de nuevo señor. – Tipx

+0

Me alegro de estar de servicio. Esa publicación es de Marc Gravell ... también es muy conocido en SO :) –

+0

¿Cómo se compara esto con la respuesta de OP publicada a continuación? – Armbrat

0

No, no es posible convertir una función actualmente virtual en una función abstracta. La única forma de aplicar esto sería crear otra función que sea abstracta, como sugirió. Este es posiblemente un enfoque más apropiado (y estoy de acuerdo con eso).

2

acabo de saber qué hacer para conseguir exactamente el comportamiento que quería:

public abstract class AAA 
{ 
    protected abstract string ToStringSpecific(); 
    protected string ToString() 
    { 
    // Base Stuff 
    ... 
    // Use this.ToStringSpecific(); 
    } 
} 

public class BBB : AAA 
{ 
    protected override string ToStringSpecific() 
    { 
    // Specific Stuff 
    } 
} 
+0

Creo que debería haber editado su pregunta original ... – Armbrat

+0

De hecho, voy a editar la pregunta (y el título) para que pueda ayudar a alguien a encontrar este tema, pero dejaré mi solución aquí. (Si no se debe hacer de esta manera, no habrá un botón "Anwser Your Question") – Tipx

+0

Acabo de volver a leer la segunda parte de mi comentario y "suena" arrogante. Lo siento, no era mi intención, y no puedo editar el comentario. Me disculpo. – Tipx

Cuestiones relacionadas