.NET 帮助

C# 虚拟与抽象(开发人员如何运作)

发布 2024年四月29日
分享:

在 C# 中、 虚拟方法 可以在派生类中重写,而抽象方法必须在派生类中重写。这使得面向对象编程具有灵活的行为和多态性。这两个概念使面向对象编程具有灵活性和可重用性。本文将解释抽象方法和虚拟方法的具体内容,提供清晰的示例,并重点介绍它们在编码中的实际用途。我们还将探讨 IronPDF 在文章的后面。

抽象类和方法

抽象类是一种不能直接实例化的特殊类型的类。相反,它是其他类的蓝图。抽象类可能包含抽象方法,即在抽象类中声明但必须在具体派生类中实现的方法。

public abstract class Vehicle
{
// abstract method to be implemented in non abstract child class
    public abstract void DisplayInfo();
}
public abstract class Vehicle
{
// abstract method to be implemented in non abstract child class
    public abstract void DisplayInfo();
}
Public MustInherit Class Vehicle
' abstract method to be implemented in non abstract child class
	Public MustOverride Sub DisplayInfo()
End Class
VB   C#

在本例中,Vehicle 类是抽象类,而 DisplayInfo 是一个抽象方法。DisplayInfo 方法在 Vehicle 类中没有任何实现。它迫使派生类提供自己对该方法的定义。

虚拟方法

虚拟方法是基类中的方法,这些方法有默认的实现,但可以在派生类中重写。virtual 关键字用于将方法声明为虚拟方法。派生类使用覆盖关键字来提供方法的具体实现,这有助于理解子类如何覆盖父类的虚拟方法。

// non abstract class
public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some generic animal sound");
    }
}
// non abstract class
public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some generic animal sound");
    }
}
' non abstract class
Public Class Animal
	Public Overridable Sub Speak()
		Console.WriteLine("Some generic animal sound")
	End Sub
End Class
VB   C#

在这里,Animal 类有一个默认实现的虚拟方法 Speak 。派生类可以使用覆盖关键字覆盖该方法,以提供特定的动物声音。

结合虚拟方法和抽象方法

一个类可以同时拥有抽象方法和虚拟方法。抽象方法没有实现,必须在派生类中覆盖,而虚拟方法有默认实现,派生类可以选择覆盖。

考虑这样一种情况:您正在构建一个为不同类型车辆建模的系统,每种车辆都有自己的信息显示方式。下面介绍如何使用抽象方法和虚拟方法:

public abstract class Vehicle
{
    // Abstract method
    public abstract void DisplayInfo();
    // Virtual method
    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started with default configuration.");
    }
}
public abstract class Vehicle
{
    // Abstract method
    public abstract void DisplayInfo();
    // Virtual method
    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started with default configuration.");
    }
}
Public MustInherit Class Vehicle
	' Abstract method
	Public MustOverride Sub DisplayInfo()
	' Virtual method
	Public Overridable Sub StartEngine()
		Console.WriteLine("Engine started with default configuration.")
	End Sub
End Class
VB   C#

在这个Vehicle类中,DisplayInfo是一个抽象方法,强制所有派生类实现其显示信息的方式。 *然而,StartEngine 提供了启动引擎的默认方法,如果需要,继承类可以重写该方法。

派生类示例

现在,让我们定义一个非抽象子类 Car 类,它继承自 Vehicle 并实现抽象方法,同时可选择覆盖虚拟方法:

public class Car : Vehicle
{
// public override void abstractmethod
    public override void DisplayInfo()
    {
        Console.WriteLine("This is a car.");
    }
    public override void StartEngine()
    {
        Console.WriteLine("Car engine started with custom settings.");
    }
}
public class Car : Vehicle
{
// public override void abstractmethod
    public override void DisplayInfo()
    {
        Console.WriteLine("This is a car.");
    }
    public override void StartEngine()
    {
        Console.WriteLine("Car engine started with custom settings.");
    }
}
Public Class Car
	Inherits Vehicle

' public override void abstractmethod
	Public Overrides Sub DisplayInfo()
		Console.WriteLine("This is a car.")
	End Sub
	Public Overrides Sub StartEngine()
		Console.WriteLine("Car engine started with custom settings.")
	End Sub
End Class
VB   C#

在这里,Car类为抽象方法DisplayInfo和虚拟方法StartEngine提供了具体实现。

区别和何时使用

  • 当所有派生类都必须提供自己的方法实现时,使用抽象方法。
  • 当派生类可以选择覆盖默认值或提供额外行为时,使用虚拟方法。

抽象方法和虚拟方法是 C# 的强大功能,可帮助您编写更易于维护和重用的代码。通过将基类中的所有方法定义为抽象或虚拟方法,您可以规定哪些方法必须在派生类中重载,哪些方法可以选择重载以修改或扩展默认行为。

覆盖虚拟方法

在派生类中重写虚拟方法可以实现自定义行为,同时保留调用基类实现的选项。这可以使用 base 关键字来实现。

重写和调用基本实现的示例

public class ElectricCar : Car
{
    public override void StartEngine()
    {
        base.StartEngine(); // Call the base class implementation
        Console.WriteLine("Electric car engine started with energy-saving mode.");
    }
}
public class ElectricCar : Car
{
    public override void StartEngine()
    {
        base.StartEngine(); // Call the base class implementation
        Console.WriteLine("Electric car engine started with energy-saving mode.");
    }
}
Public Class ElectricCar
	Inherits Car

	Public Overrides Sub StartEngine()
		MyBase.StartEngine() ' Call the base class implementation
		Console.WriteLine("Electric car engine started with energy-saving mode.")
	End Sub
End Class
VB   C#

在本例中,作为 Car 子类的 ElectricCar 重写了从父类继承的 StartEngine 方法。它调用了基类的实现,并添加了电动汽车特有的额外行为。

实现抽象和非抽象类

了解抽象类和非抽象类在软件开发中的实际区别和应用至关重要。抽象类是其他类的模板,而非抽象类则用于实例化对象。在使用抽象类和非抽象类之间做出选择,取决于您是否需要创建一个不宜单独实例化的基类。

IronPDF:C# PDF Library

C# 虚拟与抽象(如何为开发人员所用):图 1 - IronPDF

IronPDF 是一个全面的 PDF 库,可直接在 .NET 应用程序中生成、编辑和阅读 PDF 文档。该工具的突出特点是能创建 直接从 HTML 字符串生成 PDFHTML 文件和 URL。开发人员可以在 C# 项目中通过编程方式创建、修改和提取 PDF 内容。让我们在本文的背景下探讨一个 IronPDF 的示例。

IronPDF 的主要功能是转换 HTML 转 PDF确保保留布局和样式。此工具非常适合从网页内容创建报告、发票和文档的PDF。它支持将HTML文件、URL和HTML字符串转换为PDF文件。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
VB   C#

代码示例

下面是一个简单明了的实际代码示例,用于说明在扩展 IronPDF 功能时如何使用 virtualabstract 关键字:

public abstract class PdfReportGenerator
{
    // Use abstract method to force derived classes to implement their custom PDF generation logic.
    public abstract void GenerateReport(string filePath);
    // A virtual function allows derived classes to override the default implementation of PDF setup.
    public virtual void SetupPdfGenerator()
    {
        // Default PDF setup logic that can be overridden by derived classes.
        IronPdf.Installation.TempFolderPath = @"F:\TempPdfFiles";
    }
}
public class MonthlyReportGenerator : PdfReportGenerator
{
    // Override abstract method to provide specific implementation using override modifier.
    public override void GenerateReport(string filePath)
    {
        var pdf = new ChromePdfRenderer();
        pdf.RenderHtmlAsPdf("<h1>Monthly Report</h1> <p>Add Your report content here....</p>").SaveAs(filePath);
    }
    // Optionally override the virtual method to customize the setup.
    public override void SetupPdfGenerator()
    {
        base.SetupPdfGenerator();
        // Additional setup logic specific to monthly reports.
        IronPdf.Installation.TempFolderPath = @"F:\MonthlyReports";
    }
}
class Program
{
    static void Main(string [] args)
    {
        License.LicenseKey = "License-Key";
        PdfReportGenerator reportGenerator = new MonthlyReportGenerator();
        reportGenerator.SetupPdfGenerator();
        reportGenerator.GenerateReport(@"F:\MonthlyReports\MonthlyReport.pdf");
        Console.WriteLine("Report generated successfully.");
    }
}
public abstract class PdfReportGenerator
{
    // Use abstract method to force derived classes to implement their custom PDF generation logic.
    public abstract void GenerateReport(string filePath);
    // A virtual function allows derived classes to override the default implementation of PDF setup.
    public virtual void SetupPdfGenerator()
    {
        // Default PDF setup logic that can be overridden by derived classes.
        IronPdf.Installation.TempFolderPath = @"F:\TempPdfFiles";
    }
}
public class MonthlyReportGenerator : PdfReportGenerator
{
    // Override abstract method to provide specific implementation using override modifier.
    public override void GenerateReport(string filePath)
    {
        var pdf = new ChromePdfRenderer();
        pdf.RenderHtmlAsPdf("<h1>Monthly Report</h1> <p>Add Your report content here....</p>").SaveAs(filePath);
    }
    // Optionally override the virtual method to customize the setup.
    public override void SetupPdfGenerator()
    {
        base.SetupPdfGenerator();
        // Additional setup logic specific to monthly reports.
        IronPdf.Installation.TempFolderPath = @"F:\MonthlyReports";
    }
}
class Program
{
    static void Main(string [] args)
    {
        License.LicenseKey = "License-Key";
        PdfReportGenerator reportGenerator = new MonthlyReportGenerator();
        reportGenerator.SetupPdfGenerator();
        reportGenerator.GenerateReport(@"F:\MonthlyReports\MonthlyReport.pdf");
        Console.WriteLine("Report generated successfully.");
    }
}
Public MustInherit Class PdfReportGenerator
	' Use abstract method to force derived classes to implement their custom PDF generation logic.
	Public MustOverride Sub GenerateReport(ByVal filePath As String)
	' A virtual function allows derived classes to override the default implementation of PDF setup.
	Public Overridable Sub SetupPdfGenerator()
		' Default PDF setup logic that can be overridden by derived classes.
		IronPdf.Installation.TempFolderPath = "F:\TempPdfFiles"
	End Sub
End Class
Public Class MonthlyReportGenerator
	Inherits PdfReportGenerator

	' Override abstract method to provide specific implementation using override modifier.
	Public Overrides Sub GenerateReport(ByVal filePath As String)
		Dim pdf = New ChromePdfRenderer()
		pdf.RenderHtmlAsPdf("<h1>Monthly Report</h1> <p>Add Your report content here....</p>").SaveAs(filePath)
	End Sub
	' Optionally override the virtual method to customize the setup.
	Public Overrides Sub SetupPdfGenerator()
		MyBase.SetupPdfGenerator()
		' Additional setup logic specific to monthly reports.
		IronPdf.Installation.TempFolderPath = "F:\MonthlyReports"
	End Sub
End Class
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key"
		Dim reportGenerator As PdfReportGenerator = New MonthlyReportGenerator()
		reportGenerator.SetupPdfGenerator()
		reportGenerator.GenerateReport("F:\MonthlyReports\MonthlyReport.pdf")
		Console.WriteLine("Report generated successfully.")
	End Sub
End Class
VB   C#

在这个自定义实现示例中,PdfReportGenerator 是一个抽象类,定义了生成 PDF 报告的契约,包含一个生成报告的方法和一个可选择覆盖的虚拟设置方法。 MonthlyReportGenerator 是一个具体实现,它提供了生成月度报告的具体方法,并通过覆盖虚拟方法自定义设置。

C# Vitrual Vs Abstract(如何为开发人员工作):图 2 - 报告输出

结论

C# Vitrual Vs Abstract(如何为开发人员工作):图 3 - 许可证

了解并有效使用虚拟方法和抽象方法可以大大提高 C# 编程能力。请记住,抽象方法需要派生类提供实现,而虚拟方法允许对默认实现进行可选覆盖。IronPDF 库提供了一个 免费试用许可证价格从 749 美元起,可为您的 PDF 需求提供全面的解决方案。

< 前一页
C# 部分类(对开发者的作用)
下一步 >
如何使用ASP.NET生成PDF报告

准备开始了吗? 版本: 2024.9 刚刚发布

免费NuGet下载 总下载量: 10,731,156 查看许可证 >