C # абстрактный класс наследование статического поля - PullRequest
16 голосов
/ 22 августа 2010

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

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

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

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

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

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

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

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

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

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

EDIT:

Модель должна быть членом класса "ModelObject", она НЕ должна быть одиночной или чем-то еще.

EDIT2:

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

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

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

Ответы [ 3 ]

17 голосов
/ 22 августа 2010

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

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

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

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

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

6 голосов
/ 22 августа 2010

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

abstract class AbstractClass
{
}

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

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

3 голосов
/ 22 августа 2010

Как насчет фабрики, чтобы отделить ваши классы от унаследованной модели:

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