我正在尝试基于this example为MigraDoc创建一个库,该库支持不同类型的文档。我的想法是使用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...
}
但是如果创建继承了CreatePage()
的继承类,那么将从CreateDocument()
调用哪个方法?
CreatePage()
的方法答案 0 :(得分:5)
由于方法为virtual
,因此将调用正确的版本。工作中的机制称为polymorphism。
实际上,CreateDocument
甚至不需要是虚拟的即可工作(除非您打算在另一个基类中覆盖它)。
您可以在使用simple test program时看到它(请注意,我制作了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()
符合预期。