从基调用虚方法

Calling virtual method from base

我正在尝试基于 this example 为 MigraDoc 创建一个库,它支持不同类型的文档。我的想法是创建一个基础 class,其中包含 CreatePage() 的虚方法(负责页面布局的方法)。但是,概念是 CreatePage() 应该从用户调用的名为 CreateDocument() 的方法中调用。 las,可以覆盖 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...
}

但是如果create inherited class,覆盖了CreatePage(),那么会从CreateDocument()调用哪个方法?

因为方法是virtual,所以会调用正确的版本。工作机制称为 polymorphism

事实上 CreateDocument 甚至不需要虚拟就可以工作(除非你打算在另一个基础 class 中覆盖它)。

你可以看到它与 simple test program 一起工作(注意我做了 CreatePage protected 所以它不能从外部 DocumentWriter 或其基础 classes)。请注意,即使我通过基本 class 类型显式调用 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()

符合预期。