2009-07-17 58 views
7

我有這樣的情況,當AbstractMethod方法是從ImplementClass調用我要強制執行MustBeCalled方法在抽象類被調用。我從來沒有遇到過這種情況。謝謝!如何在調用重寫方法時強制執行方法調用(在基類中)?

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+0

如何通過子類調用AbstractClass.AbstractMethod來引發一個事件來調用AbstractClass.MustBeCalled。但仍然不確定如何去做。 – Jeff 2009-07-17 01:46:49

回答

8

的選擇是有抽象類做主叫這種方式。否則,c#中無法要求繼承類以某種方式實現方法。

public abstract class AbstractClass 
{ 
    public void PerformThisFunction() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 

    //could also be public if desired 
    protected abstract void AbstractMethod(); 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 

這樣做會在抽象類所需的面向公衆的方法,從而在事情是如何以及以什麼順序叫抽象類,同時還允許具體類,以提供所需的功能。

+0

***謝謝。 *** – Jeff 2009-07-17 01:55:12

+0

我也使用過這種模式。我相信這實際上是四人幫的設計模式之一,但我沒有我的書來證實這一點。 – MedicineMan 2009-07-17 01:56:42

-1

爲什麼不能在Implement類的AbstractMethod()中調用該方法?

6

如何

public abstract class AbstractClass 
{ 
    public void AbstractMethod() 
    { 
     MustBeCalled(); 
     InternalAbstractMethod(); 
    } 

    protected abstract void InternalAbstractMethod(); 

    public void MustBeCalled() 
    { 
     //this must be called when AbstractMethod is invoked 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    protected override void InternalAbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
    } 
} 
+1

在這個實現中,我不認爲你強迫用戶調用MustBeCalled。當調用AbstractClass.AbstractMethod時,將調用ImplementClass.AbstractMethod,但MustBeCalled不是。我相信yshuditelu有更好的解決方案 – MedicineMan 2009-07-17 01:55:48

0

一件事前面的解決方案忽視的是,ImplementClass可以重新定義MethodToBeCalled而不是調用MustBeCalled -

public abstract class AbstractClass 
{ 
    public abstract void AbstractMethod(); 

    private void MustBeCalled() 
    { 
     //will be invoked by MethodToBeCalled(); 
     Console.WriteLine("AbstractClass.MustBeCalled"); 
    } 

    public void MethodToBeCalled() 
    { 
     MustBeCalled(); 
     AbstractMethod(); 
    } 
} 

public class ImplementClass : AbstractClass 
{ 
    public override void AbstractMethod() 
    { 
     Console.WriteLine("ImplementClass.InternalAbstractMethod"); 
    } 

    public new void MethodToBeCalled() { 
     AbstractMethod(); 
    } 
} 

如果只有C#允許非重寫方法加以密封 - 像Java的final關鍵字!

我能想到的唯一方法就是使用委託而不是繼承,因爲可以將定義爲密封。我正在使用一個名稱空間和「內部」訪問修飾符來阻止提供實現類的新實現。另外,要覆蓋的方法必須定義爲受保護的,否則用戶可以直接調用它。

namespace Something 
{ 

    public sealed class OuterClass 
    { 
     private AbstractInnerClass inner; 

     public OuterClass(AbstractInnerClass inner) 
     { 
      this.inner = inner; 
     } 

     public void MethodToBeCalled() 
     { 
      MustBeCalled(); 
      inner.CalledByOuter(); 
     } 

     public void MustBeCalled() 
     { 
      //this must be called when AbstractMethod is invoked 
      System.Console.WriteLine("OuterClass.MustBeCalled"); 
     } 
    } 

    public abstract class AbstractInnerClass 
    { 
     internal void CalledByOuter() 
     { 
      AbstractMethod(); 
     } 

     protected abstract void AbstractMethod(); 
    } 
} 

public class ImplementInnerClass : Something.AbstractInnerClass 
{ 
    protected override void AbstractMethod() 
    { 
     //when called, base.MustBeCalled() must be called. 
     //how can i enforce this? 
     System.Console.WriteLine("ImplementInnerClass.AbstractMethod"); 
    } 

    public new void CalledByOuter() 
    { 
     System.Console.WriteLine("doesn't work"); 
    } 
} 
相關問題