2010-08-22 28 views
15

Siento que me he saltado una clase C# o dos, pero aquí está mi dilema:C# campo estático clase abstracta herencia

tengo una clase abstracta de la que derivo múltiples clases hijas.

Sé con certeza que para cada una de las clases secundarias tendré un constructor que necesita un determinado objeto estático como modelo y este objeto será diferente para cada una de las clases secundarias.

Mi primer enfoque fue hacer un objeto público estático en la clase primaria abstracta y luego, antes de comenzar a crear cualquier instancia de las clases secundarias, lo modificaría para cada una de ellas, pero resulta que de esta manera de hecho solo hace UNO objeto estático, para la clase abstracta, y cada una de sus clases infantiles lo usa.

¿Cómo podría solucionar el problema?

Para ser más exactos, aquí está el pseudocódigo:

La clase abstracta padres:

abstract class AbstractClass 
{ 
    static public ModelObject Model; 
    ... 
} 

Una de las clases hijas:

class Child : AbstractClass 
{ 
    ... 
    public Child() 
    { 
     this.someField = Model.someField; 
    } 
} 

EDIT:

El El modelo debe ser miembro de la clase "ModelObject", NO debe ser un singleton o anythi ng else.

Edit2:

Para ser aún más exacta, he elegido esta implementación de una partida de ajedrez: Tengo una clase abstracta de las piezas de ajedrez y las clases hijas representan las piezas de hormigón del juego: peones, caballeros , etcétera.

La clase abstracta hereda de MeshMatObject, una clase que representa objetos genéricos 3d con la funcionalidad básica, como rotaciones, mallas, materiales, texturas, etc., y define métodos abstractos para piezas de ajedrez, como GetPossibleMoves().

El objeto Modelo del que hablaba anteriormente es miembro de MeshMatObject y, en mi opinión, debería definirse fuera de la clase solo una vez y luego usarse para todas las piezas. Quiero decir: por ejemplo, todos los peones tienen la misma malla y textura, por lo que no veo el sentido de dar un modelo como parámetro cada vez que quiera hacer un peón.

+2

¿De qué manera necesita AbstractClass acceder al Modelo? – dtb

+2

Debería considerar pasar una instancia de modelo a los constructores de sus subclases en lugar de usar dicho campo estático. – Trillian

+0

Estoy de acuerdo con Trillian. Tener el modelo estático realmente está violando el espíritu de encapsulación aquí. –

Respuesta

6

tiendo a usar algo similar a la solución de @ shf301.Dependiendo de sus necesidades fuere útil para configurar la clase base como:

abstract class AbstractClass 
{ 
} 

abstract class AbstractClass<TModel> : AbstractClass 
    where TModel : ModelObject 
{ 
    static public TModel Model; 
    ... 
} 

Esto me permite una clase base común de que puedo trabajar con funciones no genéricos. Esto también permite que los tipos derivados elijan el tipo de modelo exacto y puedan reducir el lanzamiento.

+0

¡Funciona perfecto! Solo que el "..." está en "AbstractClass". Una implementación agradable y simple, gracias. Una cosa más: ¿hay alguna penalización en el rendimiento o tal con esta implementación? No veo ninguna razón por la que debería ser así, especialmente con la función "optimizar código" de VS, pero solo me aseguro. – cantrem

+0

EDITAR: En mi caso, la restricción de tipo debe ser AbstractClass; entonces las clases secundarias se declararían como shf301. Esto se debe a que necesito la implementación solo para los niños de AbstractClass. algo como: AbstractClass : AbstractClass donde T: AbstractClass y el niño: ChildClass: AbstractClass cantrem

15

Puede desplazarse por el campo estático compartido haciendo que su clase abstracta sea genérica. Cada clase genérica obtendrá su propia copia de los campos estáticos.

abstract class AbstractClass<T> 
{ 
    static public ModelObject Model; 
    ... 
} 

Luego cada clase secundaria usará una instancia diferente del campo estático.

class Child : AbstractClass<Child> 
{ 
    ... 
    public Child() 
    { 
     this.someField = Model.someField; 
    } 
} 

No importa que AbstractClass no haga referencia al parámetro genérico. Solo lo está usando para otorgar a cada clase secundaria una instancia única de la clase base.

+1

Gracias por la entrada, está a mitad de camino. La otra mitad proviene de Justin R. Si hubiera utilizado solo su solución, no habría tenido forma de operar con solo objetos AbstractClass. Por ejemplo, me habría costado diseñar una serie 2D de piezas abstractas de ajedrez. De todos modos, es muy bueno saber que con las clases genéricas cada niño recibe una copia del campo estático. – cantrem

3

¿Qué tal una fábrica para desacoplar sus clases a partir de un modelo heredado:

public static class ModelObjectFactory 
{ 
    public static ModelObject GetModel<T>(T obj) 
    { 
     // return ModelObject according to type of parameter 
    } 
} 

class Child 
{ 
    public Child() 
    { 
     ModelObject mo = ModelObjectFactory(this); 
     this.someField = mo.someField; 
    } 
} 
+0

Una fábrica habría funcionado mejor en otros casos. En este particular, creo que hubiera complicado la situación (si es que se trata de una palabra); ¡pero gracias por la idea! – cantrem

+0

Tener objetos con una sola responsabilidad nunca complica las cosas. Verifique los principios SÓLIDOS. -1 al comentario si eso fuera posible :) –

Cuestiones relacionadas