C# 从基类到与方法同名的类调用方法
小结:B接收A的呼叫,并自动启动start方法 假设我们有一个类A:A有一个名为Start的函数,该Start函数最初是从另一个类调用的(让我们将该类称为C),一旦调用了它,它应该使用Start(并使用它的基类)调用所有类中的每个方法,使用相同的方法 我们有B:一个使用a作为基类的类,它的任务是从a(最初由C调用)接收Start方法。现在我可以通过直接从A调用B的方法来实现这一点,但在本例中,B可以被命名为任何名称,多个类继承同一个方法 这很有用,因为我不想将所有变量分配给一个启动函数。相反,您可以创建一个允许调用相同函数名的函数 例如:下面是我认为它会是什么样子C# 从基类到与方法同名的类调用方法,c#,methods,C#,Methods,小结:B接收A的呼叫,并自动启动start方法 假设我们有一个类A:A有一个名为Start的函数,该Start函数最初是从另一个类调用的(让我们将该类称为C),一旦调用了它,它应该使用Start(并使用它的基类)调用所有类中的每个方法,使用相同的方法 我们有B:一个使用a作为基类的类,它的任务是从a(最初由C调用)接收Start方法。现在我可以通过直接从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();
}
在类层次结构中的每个
开始
类中使用它您从未创建过B
或其他类
对象。因此,无法调用它们的Start
方法
继承则相反。派生类可以调用其基类成员,因为它知道其祖先并继承其所有成员(字段、属性和方法)。另一端的基类(A
)不知道它的后代
必须使用可以在派生类中重写的虚拟
方法。例如:
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();
这将输出:
启动
启动B
因为派生类型与它们的基类型是赋值兼容的,所以您也可以这样做
var list = new List<A> { new B(), new A() };
foreach (A a in list) {
a.Start();
}
其中前两行来自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”
应该来自哪里?无论是A
,还是B
都没有这样的字段,并且从未创建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();
谢谢,我现在知道我必须添加脚本的每个实例,并循环每个实例,直到它找到具有相同基类的类型。每个startable类都可以实现一个
IStartable
接口。这些对象可以订阅全局启动事件。或者,您可以在所有类的构造函数中开始。