我有一个基类和一个继承基类。基类有几个虚函数,继承的类可以覆盖它们。但是,基类中的虚函数必须在调用继承的类重写之前运行。有没有什么方法可以先调用基类虚函数然后继承类重写。不调用base.function()。
我知道我可以简单地创建两个函数,一个被调用,另一个虚拟。但有没有办法可以保持同样的名字?我知道我可能需要改变一些事情。
class myBase
{
public virtual myFunction()
{ /* must-run code, Called first */ }
}
class myInherited : myBase
{
public override myFunction()
{ /* don't use base.myFunction();,
called from base.myFunction(); */ }
}
类似问题here。
答案 0 :(得分:67)
C#不支持自动执行此操作,但是 您可以使用template method pattern强制执行此操作。例如,假设你有这个代码:
abstract class Animal
{
public virtual void Speak()
{
Console.WriteLine("I'm an animal.");
}
}
class Dog : Animal
{
public override void Speak()
{
base.Speak();
Console.WriteLine("I'm a dog.");
}
}
这里遇到的麻烦是,任何继承自Animal
的类都需要调用base.Speak();
来确保执行基本行为。您可以通过采用以下(略有不同)的方法自动强制执行此操作:
abstract class Animal
{
public void Speak()
{
Console.WriteLine("I'm an animal.");
DoSpeak();
}
protected abstract void DoSpeak();
}
class Dog : Animal
{
protected override void DoSpeak()
{
Console.WriteLine("I'm a dog.");
}
}
在这种情况下,客户端仍然只能看到多态Speak
方法,但保证Animal.Speak
行为可以执行。问题是如果你有进一步的继承(例如class Dachshund : Dog
),你必须创建另一个抽象方法,如果你希望保证Dog.Speak
能够执行。
答案 1 :(得分:49)
可以在.NET Framework中找到的常见解决方案是将方法拆分为公共方法XXX
和受公共方法调用的受保护虚拟方法OnXXX
。对于您的示例,它看起来像这样:
class MyBase
{
public void MyMethod()
{
// do something
OnMyMethod();
// do something
}
protected virtual void OnMyMethod()
{
}
}
和
class MyInherited : MyBase
{
protected override void OnMyMethod()
{
// do something
}
}
答案 2 :(得分:2)
public abstract class BaseTemp
{
public void printBase() {
Console.WriteLine("base");
print();
}
public abstract void print();
}
public class TempA: BaseTemp
{
public override void print()
{
Console.WriteLine("TempA");
}
}
public class TempB: BaseTemp
{
public override void print()
{
Console.WriteLine("TempB");
}
}
答案 3 :(得分:0)
除了你已经命名的两种方式之外,没有办法做你正在寻找的东西。
您可以在基类中创建2个函数,一个被调用,另一个虚拟。
或者你在子类中调用base.functionName。
答案 4 :(得分:0)
不完全是。但我使用抽象方法做了类似的事情。
抽象方法必须由派生类覆盖。抽象过程是虚拟的,因此您可以确定当基类调用它们时,将调用派生类的版本。然后让你的基类的“必须运行代码”在运行后调用抽象过程。瞧,您的基类的代码总是首先运行(确保基类proc不再是虚拟的),然后是派生类的代码。
class myBase
{
public /* virtual */ myFunction() // remove virtual as we always want base class's function called here
{ /* must-run code, Called first */
// call derived object's code
myDerivedMustcallFunction();
}
public abstract myDerivedMustCallFunction() { /* abstract functions are blank */ }
}
class myInherited : myBase
{
public override myDerivedMustCallFunction()
{ /* code to be run in derived class here */ }
}
答案 5 :(得分:0)
你怎么看待这个?
class myBase
{
public void myFunctionWrapper()
{
// do stuff that must happen first
// then call overridden function
this.myFunction();
}
public virtual void myFunction(){
// default implementation that can be overriden
}
}
class myInherited : myBase
{
public override void myFunction()
{
}
}