2016-04-28 4 views
1

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

В каждом подклассе MySubclass должен быть установлен заводской метод public static MySubclass CreateFrom(ISomething something). Интерфейс его аргумента одинаковый для всех подклассов, но возвращаемый тип должен, конечно, всегда быть типом соответствующего подкласса.

Могу ли я как-то добиться этого, чтобы иметь статические методы фабрики после определения интерфейса или абстрактного метода суперкласса без создания отдельного статического заводского класса для каждого отдельного подкласса?

ответ

1

Если ISomething всегда одного и того же (или, по крайней мере, общий) типа, вы могли бы сделать метод CreateFrom из superclass generic и вызывать конструктор унаследованного класса с параметром. Просто убедитесь, что все ваши унаследованные классы имеют этот конструктор (не уверен, но я не думаю, что есть способ «заставить» шаблон конструктора).

public abstract class SuperClass 
{ 
    public static T CreateFrom(ISomething something) 
    { 
     return (T)Activator.CreateInstance(typeof(T), something); 
    } 
} 

public class InheritedClass : SuperClass 
{ 
    public InheritedClass(ISomething something) 
    {} 
} 

Таким образом, вы можете создать экземпляры по телефону

SuperClass.CreateFrom<InheritedClass>(something); 

Или вы разделяете создание и инициализация:

public abstract class SuperClass 
{ 
    protected abstract void Initialize(ISomething something); 

    public static T CreateFrom(ISomething something) where T : new() 
    { 
     T result = new T(); 
     T.Initialize(something); 
    } 
} 

public class InheritedClass : SuperClass 
{ 
    public InheritedClass() 
    {} 

    protected override Initialize(ISomething something) 
    {} 
} 
0

Вы не можете определить статические элементы на интерфейсах, поскольку статические члены принадлежат определенному классу. Однако я не могу представить себе причину использовать это. Вы должны спросить себя, почему вам нужна такая функциональность. Нужно ли подклассу создавать экземпляр самостоятельно или же легко можно сделать с другим независимым (заводским) классом?

Просто создайте один простой заводский класс с общим параметром, который указывает, что создавать.

class Factory<T> where T: new() 
{ 
    T CreateFrom(ISomething param) 
    { 
     return new T(); 
    } 

} 

Теперь вы можете просто назвать это так:

var myFactory = new Factory<MyClass>(); 
myFactory.CreateFrom(mySomething); 
+0

но не статический ... – buffjape

+1

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

0

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

public abstract class Element 
{ 
    protected virtual void copyFrom(Element other) 
    { 
    } 

    protected abstract Elememt newInstanceOfMyType(); 
    public object clone() 
    { 
     var instance= newInstanceOfMyType(); 
     instance.copyFrom(this); 
     return instance;   
    } 
} 

Теперь все мои подклассов, наследующих от класса Element требуется переопределить метод newInstanceOfMyType выдавать экземпляр своего типа, а затем также переопределять метод copyFrom для создания идеального клона. Теперь люди могут утверждать, почему абстрактный метод клонирования не может выполнять ту же работу? Да, оно может. Но мне нужен клонированный экземпляр подкласса, а также пустой экземпляр (без копирования чего-либо из текущего), поэтому я придумал эту архитектуру.

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