在基类之间调用与该方法同名的方法

时间:2019-03-25 14:09:13

标签: c# methods

摘要:B收到来自A的呼叫,并自动启动启动方法

假设我们有A类:A有一个名为Start的函数,该start函数最初是从另一个类中调用的(让该类称为C),并且一旦被调用,它应该使用Start(并使用它的基类),并使用相同的方法。

我们有B:一个使用A作为基类的类,它的工作是从A接收Start方法(最初由C调用)。现在,我可以简单地通过直接从A调用B的方法来做到这一点,但是在这种情况下,B可以命名为任何东西,并且多个类继承了相同的方法。

这很有用,因为我不想将所有变量分配给一个启动函数。而是可以创建一个函数,以允许调用相同的函数名称。

例如:这就是我在想的样子

class A
{
    public void Start()
    {
        // Call B's Start here...
    }
}

class B : A
{
    public void Start()
    {
        // Receive A's call ... and do stuff here
    }
}


// This time, we also need to access this start method.
// But this class could be named anything
class anotherClass : A
{
    public void Start()
    {
        // Receive A's call
    }
}

class C
{
    static void Main(string[] args)
    {
        A a = new A();

        // Maybe somehow call all start methods here
        a.Start();
    }
}

但是正如您所看到的,将调用A类中的Start,但绝不会调用B类中的start。

在更好的上下文中,我需要一种方法来调用每个类中的所有Start方法。

3 个答案:

答案 0 :(得分:1)

只需使用对基类的引用即可:

// or maybe you want to override??
public new void Start()
{
  base.Start();
}

在类层次结构中的每个Start类中使用它

答案 1 :(得分:0)

您从未创建BanotherClass对象。因此,无法调用其Start方法。

继承以相反的方式工作。派生类可以调用其基类成员,因为它知道其祖先并继承其所有成员(字段,属性,方法)。另一端的基类(A)不知道其后代。

必须使用virtual可以在派生类中使用的override方法。示例:

class A
{
    public virtual void Start()
    {
        Console.WriteLine("Starting A");
    }
}

class B : A
{
    public override void Start()
    {
        base.Start();
        Console.WriteLine("Starting B");
    }
}

现在您可以创建一个B对象并调用其Start方法

var b = new B();
b.Start();

这将输出:

Starting A
Starting B

由于派生类型与基本类型在分配上兼容,因此您也可以执行类似的操作

var list = new List<A> { new B(), new A() };
foreach (A a in list) {
    a.Start();
}
Starting A
Starting B
Starting A

前两行来自B.Start(),最后一行来自A.Start()


但这仅适用于直接血统中的类。您不能从同级调用方法。为什么?让我们举个例子:

class C : A
{
    private string s = "hello";

    public override void Start()
    {
        base.Start();
        Console.WriteLine("Starting C: " + s);
    }
}

假设您可以在B中执行以下操作:

sibling(C).Start();

"hello"的值s应该从哪里来? AB都没有这样的字段,并且从未创建过C对象。因此,您无法满足调用所有类中的每个方法的要求。但是,如果涉及到A的字段,那么它将起作用,因为B继承了这个字段。

答案 2 :(得分:0)

您不能在未初始化的类上调用方法。因此,除非初始化B的实例,否则调用A.Start()将无法调用B.Start()。另外,B应该通知A其存在。 (除非您会使用反射,但是我不认为那是您想要的)

您可以通过自定义委托将B链接到a:

class Program
{
    static void Main(string[] args) 
    {
        var a = new A();
        var b = new B();
        a.StartHandler += b.Start;
        a.Start();

        // Output:
        // A.Start() starting.
        // B.Start() called.
        // A.Start() ending.
    }
}

class A
{
    public delegate void StartMethod();
    public event StartMethod StartHandler;

    public virtual void Start()
    {
        Console.WriteLine("A.Start() starting.");
        if (this.StartHandler != null)
        {
            this.StartHandler();
        }
        Console.WriteLine("A.Start() ending.");
    }
}

class B : A
{
    public override void Start()
    {
        Console.WriteLine("B.Start() called.");
    }
}

另一个简单的选择可能是(取决于您想要的)以另一种方式通过简单继承进行操作。如果创建B的实例,则可以将其视为A的实例。因此,您不必知道实际上使用的是B类型:

class A
{
    public virtual void Start() => Console.WriteLine("A.Start()");
}

class B : A
{
    public override void Start()
    {
        Console.WriteLine("B.Start()");
        base.Start();
    }
}

// usage:
A a = new B();
a.Start();

// Output:
// B.Start()
// A.Start();