2016-04-28 64 views
1

我有一個抽象的超類和繼承自它的子類。在接口或產品類的抽象超類中定義工廠方法

每個子類MySubclass應該有一個public static MySubclass CreateFrom(ISomething something)工廠方法。其參數的接口對於所有子類都是相同的,但返回類型必須始終是相應子類的類型。

我可以以某種方式實現此目的,在接口或抽象超類方法定義之後具有靜態工廠方法,而無需爲每個單獨的子類創建單獨的靜態工廠類?

回答

1

如果ISomething是始終不變的(或至少一個共同的)類型,你可以做的了CreateFrom方法超類泛型並用參數調用繼承類的構造函數。只要確保所有的繼承類都具有該構造函數(不確定,但我認爲沒有辦法'強制'構造函數模式)。

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

我使出在similiar樣的要求,不同的解決方案。在我的超正好是一個抽象我需要創建類的實例,用它做的東西,所以我做了以下技巧:

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

現在我所有的子類從元素類繼承覆蓋newInstanceOfMyType方法所需放棄其類型的實例,然後重寫copyFrom方法以生成完美的克隆。現在人們可能會爭辯說爲什麼抽象克隆方法不能做同樣的工作?是的,它可以。但我需要克隆的子類實例以及一個空實例(不需要從當前的任何拷貝),所以我想出了這個架構。