2010-08-22 6 views
15

Я чувствую, что я пропустил C класс или два #, но вот моя дилемма:C# Наследование абстрактного класса статического поля

У меня есть абстрактный класс, от которого я вывожу несколько классов детей.

Я точно знаю, что для каждого из дочерних классов у меня будет конструктор, которому нужен определенный статический объект в качестве модели, и этот объект будет отличаться для каждого из дочерних классов.

Мой первый подход состоял в том, чтобы сделать публичный статический объект в абстрактном родительском классе, а затем, прежде чем я начну создавать какие-либо экземпляры дочерних классов, я бы изменил его для каждого из них, но оказывается, что таким образом я фактически сделать только ОДИН статический объект, для абстрактного класса, и каждый из его дочерних классов использует его.

Как я могу решить проблему?

Чтобы быть более точным, вот псевдокод:

Родитель абстрактный класс:

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

Один из дочерних классов:

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

EDIT:

Модель должна быть членом класса «ModelObject», она НЕ должна быть синглом или anythi ng else.

EDIT2:

Чтобы быть еще более точным, я выбрал эту реализацию для игры в шахматы: У меня есть абстрактный класс для шахматных фигур и дочерние классы представляют собой конкретные части игры: пешка, рыцари , и т. д.

Отличительный класс наследует от MeshMatObject, класс, который представляет общие 3D-объекты с базовой функциональностью, такие как вращения, сетки, материалы, текстуры и т. Д., И он определяет абстрактные методы для частей шахматной игры, такие как GetPossibleMoves().

Объект Model, о котором я говорил выше, является членом MeshMatObject и, на мой взгляд, должен быть определен за пределами класса только один раз, а затем использоваться для всех частей. Я имею в виду: например, все пешки имеют одинаковую сетку и текстуру, поэтому я не вижу смысла давать модель в качестве параметра каждый раз, когда вы хотите сделать пешку.

+2

Каким образом AbstractClass необходимо получить доступ к Модели? – dtb

+2

Вам следует рассмотреть возможность передачи экземпляра модели в конструкторы ваших подклассов вместо использования такого статического поля. – Trillian

+0

Я согласен с Триллиан. Наличие статической модели действительно нарушает дух инкапсуляции здесь. –

ответ

6

Я предпочитаю использовать что-то похожее на @ shf301, решение которого.В зависимости от ваших потребностей он может полезно установить базовый класс, как:

abstract class AbstractClass 
{ 
} 

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

Это позволяет мне общий базовый класс, который я могу работать в нетипичных функций. Это также позволяет производным типам выбрать точный тип модели и может сократить литье.

+0

Он отлично работает! Просто, что «...» находятся на «AbstractClass». Спасибо, спасибо. Еще одна вещь: есть ли какое-либо наказание за исполнение или подобное с этой реализацией? Я не вижу причин, почему это должно быть, особенно с функцией «оптимизировать код» VS, но просто убедившись. – cantrem

+0

EDIT: В моем случае тип constrain должен быть AbstractClass; то дочерние классы будут объявлены как shf301. Это потому, что мне нужна реализация только для детей AbstractClass. что-то вроде: AbstractClass : AbstractClass где T: AbstractClass и ребенок: ChildClass: AbstractClass cantrem

15

Вы можете обойти общее статическое поле, создав общий класс Abstract. Каждый родовой класс получит свою собственную копию статических полей.

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

Тогда каждый дочерний класс будет использовать другой экземпляр статического поля.

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

Не имеет значения, что AbstractClass не ссылается на общий параметр. Вы используете его только для того, чтобы дать каждому дочернему классу уникальный экземпляр базового класса.

+1

Спасибо за вход, это на полпути. Другая половина исходит от Джастина Р. Если бы я использовал только ваше решение, у меня не было бы возможности работать с объектами AbstractClass. Например, мне пришлось бы с трудом выложить 2D-массив абстрактных шахматных фигур. Во всяком случае, очень хорошо знать, что с родовыми классами каждый ребенок получает копию статического поля. – cantrem

3

Как насчет завода, чтобы расцепить классы от унаследованного Model:

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

В других случаях завод работал бы лучше. В этом конкретном случае я думаю, что я бы переусердствовал (если это слово) ситуацию; но спасибо за идею! – cantrem

+0

Наличие объектов с одной ответственностью никогда не усложняет ситуацию. Проверьте принципы SOLID. -1 к комментарию, если это было возможно :) –

Смежные вопросы