猿问

从基调用虚拟方法

我正在尝试基于此示例为 MigraDoc 创建一个库,该库支持不同类型的文档。我的想法是创建一个基类,并带有一个虚方法CreatePage()(负责页面布局的方法)。但是,概念是CreatePage()应该从CreateDocument()用户调用的方法调用。唉,可以覆盖CreatePage(),但它并不意味着直接调用。它看起来像这样:


public class DocumentWriter

{

    private Document document;


    public virtual void CreateDocument(IDocumentArgs args)

    {

       document = new Document();


       DefineStyles();

       CreatePage();

       FillContent(args);

    }


    public virtual void CreatePage()

    {

        // Create page layout here

    }


    // Remaining code skipped for readability...

}

但是如果创建继承的类,它会覆盖CreatePage(),那么将从中调用哪个方法CreateDocument()?


原始虚拟(非覆盖)方法

覆盖的方法 CreatePage()


三国纷争
浏览 161回答 1
1回答

慕姐4208626

由于方法是virtual,将调用正确的版本。起作用的机制称为多态性。事实上CreateDocument,甚至不需要是虚拟的就可以工作(除非你打算在另一个基类中覆盖它)。您可以在一个简单的测试程序中看到它(请注意,我编写的程序CreatePage protected不能从外部DocumentWriter或其基类调用)。请注意,即使我CreateDocument通过基类类型显式调用,它也将始终根据对象的运行时类型调用正确的版本。public class DocumentWriter{    public /*virtual*/ void CreateDocument()    {       CreatePage();    }    protected virtual void CreatePage()    {        System.Console.WriteLine("DocumentWriter.CreatePage()");    }}public class PdfDocumentWriter : DocumentWriter{    protected override void CreatePage()    {        System.Console.WriteLine("PdfDocumentWriter.CreatePage()");    }}public class HtmlDocumentWriter : DocumentWriter{    protected override void CreatePage()    {        System.Console.WriteLine("HtmlDocumentWriter.CreatePage()");    }}public static class Program{    public static void Main()    {        DocumentWriter documentWriter = new PdfDocumentWriter();        documentWriter.CreateDocument();        // Re-use the same variable.         // CreateDocumentwill still call the correct version of CreatePage.        documentWriter = new HtmlDocumentWriter();        documentWriter.CreateDocument();    }}这打印PdfDocumentWriter.CreatePage()HtmlDocumentWriter.CreatePage()正如预期的那样。
随时随地看视频慕课网APP
我要回答