这与C#有关,但实际上这个问题非常通用。
假设我有一个基类
abstract class Base {
protected List<string> MyList = new List<string>();
protected abstract void FillMyList();
}
class Derived : Base {
protected void FillMyList() {
MyList.Add("test");
MyList.Add("test2");
}
}
这没关系,派生类填充了基类中定义的MyList。
然而,除了抽象方法名称(FillMyList) - 暗示你实际上必须填充MyList - 没有任何关于这个方法意味着什么的线索。
有没有更好的方法来强制执行或(更好)强烈建议您在继承Base时必须填写MyList? 也许将FillMyList声明为:
protected abstract void FillMyList(List<string> listToFill);
你有什么建议?
答案 0 :(得分:3)
您可以使用getter将MyList转换为abstract属性,派生必须实现
public abstract class Base
{
public abstract List<int> List { get; }
}
public class Derived : Base
{
#region Overrides of Base
public override List<int> List
{
get { return new List<int> {1, 2, 3}; }
}
#endregion
}
答案 1 :(得分:1)
如何定义“填充”?如果你的意思是“添加一些元素”,那么你可以简单地添加另一个抽象方法来检索要添加的项,然后在基类中实现FillMyList
以将这些添加到列表中。例如:
abstract class Base
{
protected List<string> MyList = new List<string>();
protected abstract IEnumerable<string> GetItems();
protected void FillMyList()
{
MyList.AddRange(GetItems());
}
}
class Derived : Base
{
protected override IEnumerable<string> GetItems()
{
yield return "test";
yield return "test2";
}
}
完成此操作后,根据您的要求,将FillMyList
更改为private
可能是合适的。另请注意,Derived
中的方法必须标记为override
。
当然,有很多不同的方法可以实现这一目标。您可以简单地将MyList
属性本身设为抽象,例如,如Nagg所建议的那样。
答案 2 :(得分:1)
你可以这样做:
abstract class Base {
protected List<string> TheList
{
get {
Debug.Assert(MyList.Count != 0);
return MyList;
}
set {
Debug.Assert(value.Count != 0);
MyList = value;
}
}
private List<string> MyList = new List<string>();
}
您的派生只能通过将要进行检查的属性访问MyList。
答案 3 :(得分:0)
我认为如果出现问题(即列表未正确填充),那么在尝试使用它时应该抛出异常。这样您就可以获得正确的数据。即使类是抽象的,用户也可以将它作为一个空方法实现,所以这不是更好。