我有一个关于.NET框架中继承的一般问题,假设你有2个类,第一个叫做Parent,第二个叫做Child。孩子继承自父母。
父级希望确保每个子实例在加载时执行特定的代码段,而不管子级是否有明确指定的onLoad代码。
根据我的经验,如果我在父级而不是在子级中处理onLoad,则父级onLoad代码将触发,但如果在两个类中处理它,则仅触发子代码。
这是对的吗?如果是这样,我怎样才能确保父母的代码永远为孩子开火......
答案 0 :(得分:7)
您发现了fragile base class问题。处理它的一种方法是这种模式:
public class Parent
{
public void OnLoad()
{
// Important load stuff goes here
OnLoadInternal();
}
protected virtual void OnLoadInternal()
{
// No implmentation in parent; child can override if needed
}
}
public class Child : Parent
{
protected override void OnLoadInternal()
{
base.OnLoadInternal();
// Important load stuff, but can't break parent by omitting base call
}
}
父母保证让它的OnLoad方法做它应该做的事情,但是孩子可以通过覆盖OnLoadInternal来增加额外的处理。
答案 1 :(得分:2)
在C#中,使用子进程中的base.methodNameHere()
来调用父类的方法。
在这种情况下,从您孩子的onLoad()方法中调用base.onLoad()
来执行父代码。
答案 2 :(得分:2)
如果在基类的默认构造函数中连接行为,并在私有方法中执行该行为,则子类无法覆盖。您将失去在子类中控制此行为的能力以及各个处理程序执行的时间(以何种顺序)。
public partial class Parent : Form
{
public Parent()
{
InitializeComponent();
Load += ParentLoad;
}
private void ParentLoad(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
答案 3 :(得分:1)
不要立即调用onLoad()
,而是调用私有函数,例如beforeLoad()
。这个函数可以完成你想让父母做的所有事情,然后它会调用onLoad()
,它可以在Child类中被覆盖。
答案 4 :(得分:1)
.NET SDK中的两个已建立的模式是虚函数和事件。
虚拟功能
class Parent {
virtual protected void OnLoad() {
//code here
}
}
class Child {
protected override void OnLoad() {
base.OnLoad();
}
}
在这种情况下,您可以为子类提供完全覆盖OnLoad行为的选项,包括不执行基类OnLoad的能力(这可能是完全合法的情况)。
使用活动
或者,您可以使用事件,这是让子类进行附加工作的一种方法,而无需覆盖基类行为:
class Parent {
public event Load;
public Parent() {
this.Load+=OnLoad();
}
private void OnLoad() {
//Parent code here
}
}
class Child {
public Child() {
this.Load+=OnLoad();
}
private void OnLoad() {
//Child code here
}
}
这是真正的设计选择。如果您希望框架帮助您强制执行父代码,请转到选项2。