C# 使用接口的多态性

C# 使用接口的多态性,c#,C#,从接口IPrintHandler派生的类BasePrintHandler,实现了所需的功能。这是作为图书馆提供的 应用程序必须提供与库不同的功能(SendTopPrint)。现在,我已经从基类和接口派生了一个类 为此,我创建了一个示例 interface IPrintHandler { void SetPage(); void SendToPrint(); } class BasePrintHandler : IPrintHandler { void IPrintHan

从接口IPrintHandler派生的类BasePrintHandler,实现了所需的功能。这是作为图书馆提供的

应用程序必须提供与库不同的功能(SendTopPrint)。现在,我已经从基类和接口派生了一个类

为此,我创建了一个示例

interface IPrintHandler
{
    void SetPage();
    void SendToPrint();
}

class BasePrintHandler : IPrintHandler
{
    void IPrintHandler.SendToPrint()
    {
        Console.WriteLine("in the base print handler");
    }

    void IPrintHandler.SetPage()
    {
        Console.WriteLine("in the setpage");
    }
}

class ChildPrintHandler : BasePrintHandler,IPrintHandler
{
    private BasePrintHandler m_Printhandler;

    public ChildPrintHandler()
    {
        m_Printhandler = new BasePrintHandler();
    }

    void IPrintHandler.SendToPrint()
    {
        Console.WriteLine("in the derive class");
        IPrintHandler aPRinthandler = m_Printhandler as IPrintHandler;
        aPRinthandler.SendToPrint();
    }
}


class Program
{
    static void Main(string[] args)
    {
        IPrintHandler aLayouthandler = new ChildPrintHandler();
        aLayouthandler.SendToPrint();

        aLayouthandler.SetPage();

        Console.Read();
    }
}
  • 这个设计有多好,这个类派生自基类和接口,并且只实现所需的功能——SendToPrint

  • 这不算太糟,但在这种模式下,我更喜欢做稍微不同的事情。您的基类可能实现一些默认行为(可以完全替换),或者它可能实现一些主要需要的行为,其中子类必须记住调用基类。当我编写接口并提供一个基类来提供boiler plate实现时,我进一步使用受保护的重写:

    public interface IPrinter
    {
        void SetPage();
        void SendToPrint();
    } // eo interface IPrinter
    
    
    public class BasePrinter : IPrinter /* Could well be abstract */
    {
         protected virtual void SetPageImpl() { }      /* Also could be abstract */
         protected virtual void SendToPrintImpl() { }  /* ........ditto .....    */
    
    
         // IPrinter implementation
         public void SetPage()
         {
             SetPageImpl();
             // can do other stuff here.  Will always be called!
         } // eo SetPage
    
    
         public void SendToPrint()
         {
             SendToPrintImpl();
             // ditto
         }
    }  // eo class BasePrinter
    
    
    public class ChildPrinter : BasePrinter
    {
         // we only do something different when setting a page
         protected override void SetPageImpl()
         {
            // ChildPrinter-specifics
         } // eo SetPageImpl
    } // eo class ChildPrinter
    

    这样,我们就保持了接口的契约,提供了将始终被调用的boiler plate代码,并允许其他类更改行为。在大多数情况下,我倾向于使用抽象保护函数来实现上述功能。我也不必记得调用基类实现,也不必记得调用基类实现的顺序(覆盖的开始或结束?

    询问它您可以得到更多答案在我提供的示例中,ChildPrintHandler只实现sendtoPrint,但是如果创建了ChildPrintHandler的实例,该实例也可以调用SetPage。可以告诉我这是如何实现的吗?您可以从
    BasePrinter
    (比如
    DefaultPrinter
    )派生另一个类,该类实现了与当前类相同的功能
    ChildPrinter
    然后可以创建此实例。