从子类调用父类方法 c#

44

这个问题和我之前看到的答案有些不同,或者是我没有理解。我有一个父类,它有一个名为MyMethod()的方法和一个public Int32 CurrentRow;的变量。

public void MyMethod()
{    
     this.UpdateProgressBar();    
}

在父类中,我创建了一个 ChildClass 的新实例。

Boolean loadData = true;
if (loadData) 
{    
     ChildClass childClass = new ChildClass();    
     childClass.LoadData(this.Datatable);    
}
在子类的LoadData()方法中,我想设置父类的CurrentRow变量并调用MyMethod()函数。
我该怎么做?

1
如果您正在尝试通过表单/窗口等与数据进行通信(因为您正在加载某些数据并更新进度条),我强烈建议您遵循一些MVC或MVVM方法。 - Can Poyrazoğlu
4
MyMethod是私有的,你无法从ChildClass调用它。 - Daniel Hilgarth
4
孩子和父母之间的关联是什么?继承?聚合? - Arsen Mkrtchyan
@DanielHilgarth 发现的好,我错过了。OP,你需要将private更改为protected,以允许该方法从子类中被访问。 - Rory McCrossan
@Daniel 抱歉,我已将其编辑为公开状态。 - CR41G14
显示剩余3条评论
4个回答

85
要访问父类的属性和方法,请使用base关键字。因此,在您的子类LoadData()方法中,您将执行以下操作:
public class Child : Parent 
{
    public void LoadData() 
    {
        base.MyMethod(); // call method of parent class
        base.CurrentRow = 1; // set property of parent class
        // other stuff...
    }
}

请注意,您还必须将父类中的访问修饰符 MyMethod() 至少更改为 protected,以便子类可以访问它。


1
从 OP:在父类中,我创建了一个 ChildClass 的新实例 - 对我来说,这意味着组合而不是继承。 - Jamiec
1
我认为你可能是对的。不过,我会把这个留在这里,以防它有些用处。 - Rory McCrossan
3
这正是我需要的,尽管这不是他的问题 :). 问题标题有些令人困惑... - tbkn23
在父类中,我创建了一个ChildClass的新实例 - 这对我来说意味着可能存在递归。我喜欢它。一直到底部都是龟。 - Emyr
@Okuma.Scott 嗯,那么问题就像Emyr所说的一样 - 通过在父类中创建一个子类来创建递归。不要这样做。 - Rory McCrossan
显示剩余3条评论

11

找到解决方案。

在父类中,我声明了ChildClass()的一个新实例,然后将该类中的事件处理程序绑定到父类中的本地方法。

在子类中,我添加了一个公共事件处理程序:

public EventHandler UpdateProgress;

在父类中,我创建了一个此子类的新实例,然后将本地父事件绑定到子类中的公共 eventhandler。
ChildClass child = new ChildClass();
child.UpdateProgress += this.MyMethod;
child.LoadData(this.MyDataTable);

然后在子类的LoadData()中,我可以调用

private LoadData() {
    this.OnMyMethod();
}

在这里,OnMyMethod 是:

public void OnMyMethod()
{
     // has the event handler been assigned?
     if (this.UpdateProgress!= null)
     {
         // raise the event
         this.UpdateProgress(this, new EventArgs());
     }
}

这将在父类中运行该事件。


2
根据您的意图,使用Action委托可能比EventHandler更好。其中一个原因是,您不必担心删除事件分配,即:child.UpdateProgress -= this.MyMethod; - Quad Coders

5

针对suhendri对Rory McCrossan的回答的评论,以下是一个Action委托的示例:

在子元素中添加:

public Action UpdateProgress;  // In place of event handler declaration
                               // declare an Action delegate
.
.
.
private LoadData() {
    this.UpdateProgress();    // call to Action delegate - MyMethod in
                              // parent
}

在父元素中添加:
// The 3 lines in the parent becomes:
ChildClass child = new ChildClass();
child.UpdateProgress = this.MyMethod;  // assigns MyMethod to child delegate

3

一种方法是在构造函数中将ParentClass的实例传递给ChildClass

public ChildClass
{
    private ParentClass parent;

    public ChildClass(ParentClass parent)
    {
        this.parent = parent;
    }

    public void LoadData(DateTable dt)
    {
       // do something
       parent.CurrentRow++; // or whatever.
       parent.UpdateProgressBar(); // Call the method
    }
}

在父类内构造ChildClass时,确保将引用传递给this

if(loadData){

     ChildClass childClass = new ChildClass(this); // here

     childClass.LoadData(this.Datatable);

}

注意:这可能不是组织类的最佳方式,但它直接回答了你的问题。

编辑:在评论中,您提到有多个父类想使用ChildClass。通过引入一个接口可以实现这一点,例如:

public interface IParentClass
{
    void UpdateProgressBar();
    int CurrentRow{get; set;}
}

现在,请确保在所有父类上实现该接口,并将子类更改为以下内容:
public ChildClass
{
    private IParentClass parent;

    public ChildClass(IParentClass parent)
    {
        this.parent = parent;
    }

    public void LoadData(DateTable dt)
    {
       // do something
       parent.CurrentRow++; // or whatever.
       parent.UpdateProgressBar(); // Call the method
    }
}

现在任何实现IParentClass的东西都可以构造一个ChildClass的实例并将this传递给它的构造函数。

@CR41G14 - 你所说的“dynamic”具体指什么?是指关键字dynamic还是“任何类,而不仅仅是ParentClass”? - Jamiec
我必须传递一个构造函数吗?我能否只是“检测”调用了这个类的父类?因为我可能希望parentClass2调用这个类。如果我表达不清楚,很抱歉,这是一个继承的项目。 - CR41G14
@CR41G14 - 不,必须是ParentClass或任何继承它的类。如果两个类都需要构造一个ChildClass,那么您可以在构造函数中使childclass采用接口。我将更新答案并提供一些详细信息。 - Jamiec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接