2010-11-07 67 views
4

我需要在调用overriden之后自动调用基类方法(如构造函数call base)。例如:自动调用基本方法

class A 
{ 
    public void Fun() 
    { 
     Console.Write("Class A!"); 
    } 
} 

class B : A 
{ 
    public void Fun() 
    { 
     Console.Write("Class B!"); 
    } 
} 

我想看到的屏幕

A级上! B类!

执行下面的代码时:

B b = new B(); 
b.Fun(); 

谁能告诉我,请有什么需要在示例代码来改变或如何更好地编写得到需要的结果?谢谢。

回答

18

如果你不想显式调用它,因此确保A.Fun()被称为在派生类中做,你可以使用一种叫做template method pattern

class A 
{ 
    public void Fun() 
    { 
     Console.Write("Class A!"); 
     FunProtected(); 
    } 

    protected virtual void FunProtected() 
    { 
    } 
} 

class B : A 
{ 
    protected override void FunProtected() 
    { 
     Console.Write("Class B!"); 
    } 
} 

这将使你:

new A().Fun() -> "Class A!" 
new B().Fun() -> "Class A! Class B!" 
+0

@Kirkham感谢您纠正我的拼写,并澄清我的答案:) – 2010-11-07 18:06:55

+3

+1受保护的乐趣。你永远不知道周围有什么...... – 2013-04-24 00:58:43

8

如果你想要这样的行为,你需要改变平台/语言。 .NET不会自动调用基本方法。你需要明确地调用它。当你这样做

class A 
{ 
    public virtual void Fun() 
    { 
     Console.Write("Class A!"); 
    } 
} 

class B : A 
{ 
    public override void Fun() 
    { 
     // call the base method which will print Class A! 
     base.Fun(); 
     Console.Write("Class B!"); 
    } 
} 

现在:

B b = new B(); 
b.Fun(); 

你会得到所需要的结果也是你的方法必须是virtual或者你会在派生类中隐藏它。

+0

“另外你的方法需要是虚拟的,否则你会将它隐藏在派生类中”对于海报想要的行为,我不确定它需要是虚拟的。 – strager 2010-11-07 18:00:28

+1

@strager,如果它不是虚拟的,你会得到一个编译器警告。 – 2010-11-07 18:01:52

+1

您可以使用new关键字在不使用虚拟方法的情况下摆脱警告。 – 2010-11-07 18:20:30

2

仍然可以这样:

interface IFun 
{ 
    void Fun(); 
} 

abstract class A : IFun 
{ 
    void IFun.Fun() 
    { 
     Console.Write("Class A!"); 
     Fun(); 
    } 
    protected abstract void Fun(); 
} 

class B : A 
{ 
    protected override void Fun() 
    { 
     Console.Write("Class B!"); 
    } 
} 

IFun b = new B(); 
b.Fun(); 

这工作如果o对象引用是IFun。

+0

但我不能以这种方式创建A类的实例。已经给出了很好的答案。 – 2011-05-20 10:21:51

0

仅供参考,您可以使用将A放入B中的包装模式。下面是一个原油示例!

interface IFunClass { 
    void Fun(); 
} 

class A : IFunClass { 
    public void IFunClass.Fun() { 
     Console.Write("Class A!"); 
    } 
} 

class B : IFunClass { 
    public B(IFunClass f) { 
     this.m_SomethingFun = f; 
    } 

    public void IFunClass.Fun() { 

     this.m_SomethingFun.Fun(); 

     Console.Write("Class B!"); 
    } 

    private IFunClass m_SomethingFun; 
} 

A a = new A(); 
B b = new B(a); 

b.Fun() // will call a.Fun() first inside b.Fun()