我正在開發一個項目,它有許多從類View派生的類,其中View提供了一些常用的方法,派生類的字段引用了該視圖的特定UI元素。例如(在C#):魯棒的方法來從基類一般初始化派生類的字段?
public abstract class View
{
public virtual void Initialize(){}
public virtual void Activate(){}
public virtual void Deactivate(){}
}
public class MainScreenView : View
{
private ImageView portraitImageView;
private ImageView landscapeImageView;
public MainScreenView(ImageView portrait, ImageView landscape)
{
portraitImageView = portrait;
landscapeImageView = landscape;
}
public override Initialize()
{
base.Initialize();
portraitImageView.Initialize(); // I would like to eliminate these calls!
landscapeImageView.Initialize();
}
public ImageView GetPortrait() { return portraitImageView; }
public ImageView GetLandscape() { return landscapeImageView; }
}
public class ImageView : View
{
private Image image;
public ImageView(Image image) { this.image = image; }
public override void Initialize() { base.Initialize(); image.Show(); }
public Image GetImage() { return image; }
}
在這個例子中,我要對所有ImageViews調用初始化()時MainScreenView.Initialize被調用。這感覺容易出錯並且不方便,因爲每次將新的子視圖添加到MainScreenView組合時,都必須添加Initialize()調用。因此,我想在派生類中消除對這些調用的需求,但是我想將這些字段保留到特定於視圖的字段中。
我的想法是添加視圖基類,然後可以遞歸初始化()的集合,如下:
public abstract class View
{
private List<View> subViews;
public virtual void Initialize()
{
foreach(View in subViews) { view.Initialize(); }
}
// This gets called before Initialize() is called.
public void AddSubViews(View[] views)
{
subViews = new List<View>();
subViews.AddRange(views);
}
}
public class MainScreenView : View
{
private ImageView portraitImageView;
private ImageView landscapeImageView;
public MainScreenView()
{
portraitImageView = ???;
landscapeImageView = ???;
}
// Even if View.subViews had been protected instead of private, this couldn't return an element from the list because the required index is unknown.
public ImageView GetPortrait() { return portraitImageView; }
public ImageView GetLandscape() { return landscapeImageView; }
}
public class ImageView : View
{
private Image image;
public ImageView() { this.image = ??? }
public override void Initialize() { base.Initialize(); image.Show(); }
public Image GetImage() { return image; } // Even if View.subViews had been protected instead of private, this couldn't return an element from the list because the required index is unknown.
}
然而,因爲所有的單個子視圖現在是「匿名'(它們通過索引而不是字段名來訪問),除非我也通過派生類的構造函數添加子視圖,如我在第一個示例中所做的那樣,我無法執行傳遞給構造函數的對象與列表中的對象相同,或者從派生類的構造函數中調用AddSubViews,其中每次添加新子視圖時都手動添加子視圖...具有相同問題是在子視圖上調用Initialize()在派生類中。
所以我的問題是:是有辦法有子視圖的所有初始化調用的視圖基類正在做,同時仍能夠提供派生類特定的元素,而無需通過引用這些元素派生類的構造函數?
更喜歡在基本抽象類上使用接口(例如'IView')。您只能從C#中的單個類派生出來,並且不需要在整個程序中爲基本抽象類創建依賴項。雖然'IView'接口將是公共的,你的基類可以被「內部」保留,並隱藏其他程序集。另外,每個*特定*視圖都有自己的*特定*公共方法這一事實意味着沒有辦法真正抽象它們的用法,所以我不確定你打算如何使用這些方法。 – Groo