繁体   English   中英

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

[英]Calling a method from base class to class with same name as the method

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

假设我们有一个类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方法。

只需使用对基类的引用:

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

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

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

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

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

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();

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

您不能在未初始化的类上调用方法。 因此,除非初始化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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM