跳過到頁腳內容
.NET幫助

C# Vitrual Vs Abstract(對於開發者的運行原理)

在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
$vbLabelText   $csharpLabel

在這個例子中,Vehicle類是抽象的,DisplayInfo是抽象方法。 DisplayInfo方法在Vehicle類中沒有任何實現。 它強迫派生類提供其自身的該方法定義。

虛擬方法

虛擬方法是基類中具有默認實現的方法,但可以在派生類中被覆寫。 使用virtual關鍵字將方法聲明為虛擬。 派生類使用override關鍵字提供方法的具體實現,這有助於理解子類如何覆寫其父類的虛擬方法。

// Non-abstract class
public class Animal
{
    // Virtual method with a default implementation
    public virtual void Speak()
    {
        Console.WriteLine("Some generic animal sound");
    }
}
// Non-abstract class
public class Animal
{
    // Virtual method with a default implementation
    public virtual void Speak()
    {
        Console.WriteLine("Some generic animal sound");
    }
}
' Non-abstract class
Public Class Animal
	' Virtual method with a default implementation
	Public Overridable Sub Speak()
		Console.WriteLine("Some generic animal sound")
	End Sub
End Class
$vbLabelText   $csharpLabel

在這裡,Animal類有一個默認實現的虛擬方法Speak。 派生類可以覆寫該方法,使用override關鍵字提供特定的動物聲音。

結合虛擬和抽象方法

一個類可以同時包含抽象和虛擬方法。 抽象方法沒有實現,必須在派生類中覆寫,而虛擬方法有默認實現,派生類可以選擇性地覆寫。

考慮一種情況,您正在構建一個系統,用於建模不同類型的車輛,每種車輛都有其顯示信息的方式。 以下是如何使用抽象和虛擬方法:

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
$vbLabelText   $csharpLabel

在這個Vehicle類中,DisplayInfo是抽象方法,強迫所有派生類實現其顯示信息的方式。 然而,StartEngine提供了一種默認的啟動引擎方式,必要時可以由繼承類覆寫。

使用派生類的示例

現在,我們定義一個Car類,一個從Vehicle繼承並實現抽象方法同時可選覆寫虛擬方法的非抽象子類:

public class Car : Vehicle
{
    // Override the abstract method
    public override void DisplayInfo()
    {
        Console.WriteLine("This is a car.");
    }

    // Override the virtual method
    public override void StartEngine()
    {
        Console.WriteLine("Car engine started with custom settings.");
    }
}
public class Car : Vehicle
{
    // Override the abstract method
    public override void DisplayInfo()
    {
        Console.WriteLine("This is a car.");
    }

    // Override the virtual method
    public override void StartEngine()
    {
        Console.WriteLine("Car engine started with custom settings.");
    }
}
Public Class Car
	Inherits Vehicle

	' Override the abstract method
	Public Overrides Sub DisplayInfo()
		Console.WriteLine("This is a car.")
	End Sub

	' Override the virtual method
	Public Overrides Sub StartEngine()
		Console.WriteLine("Car engine started with custom settings.")
	End Sub
End Class
$vbLabelText   $csharpLabel

在這裡,Car類為抽象方法DisplayInfo和虛擬方法StartEngine提供了具體的實現。

差異和何時使用

  • 當所有的派生類都必須提供它們自己的方法實現時,使用抽象方法。
  • 當派生類應該有選擇性覆寫默認或提供額外行為的選擇時,使用虛擬方法。

抽象和虛擬方法是C#中強大的功能,能夠讓您編寫出更具可維護性和可重用的代碼。 通過在基類中定義方法為抽象或虛擬,您可以指示哪些方法必須在派生類中覆寫,哪些方法可以選擇性地覆寫以修改或擴展默認行為。

覆寫虛擬方法

在派生類中覆寫虛擬方法允許自定義行為,同時保留調用基類實現的選項。 這是通過使用base關鍵字來實現的。

覆寫和調用基類實現的示例

public class ElectricCar : Car
{
    // Override the StartEngine method
    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
{
    // Override the StartEngine method
    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

	' Override the StartEngine method
	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
$vbLabelText   $csharpLabel

在這個例子中,ElectricCar作為Car的子類,覆寫了從其父類繼承的StartEngine方法。 它調用了基類實現並添加了電動車的特定行為。

實現抽象和非抽象類

在軟件開發中,了解抽象類和非抽象類的實際差異和應用是很重要的。 抽象類作為其他類的模板,而非抽象類用於實例化對象。 選擇使用抽象類還是非抽象類取決於您是否需要創建一個不應該自行實例化的基類。

IronPDF:C# PDF 庫

C#虛擬與抽象(開發人員如何使用):圖1 - IronPDF

IronPDF是一個全面的PDF庫,用於在.NET應用程序中直接生成、編輯和閱讀PDF文檔。 此工具因其能夠直接從HTML字符串、文件和URL創建PDF而突出。 開發人員可以在C#項目中以編程方式創建、修改和提取PDF內容。 讓我們探索IronPDF在我們文章中的例子。

IronPDF的主要功能是將HTML轉換為PDF,確保布局和樣式得以保留。 這個工具非常適合從網頁內容創建報告、發票和文檔的PDF。 它支持將HTML文件、URL和HTML字符串轉換為PDF文件。

using IronPdf;

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

        // 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");

        // 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");

        // 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();

        // 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");

        // 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");

        // 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()

		' 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")

		' 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")

		' 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
$vbLabelText   $csharpLabel

代碼示例

這裡有一個簡單的實際代碼示例,以說明如何在擴展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
    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
    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
	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
$vbLabelText   $csharpLabel

在這個自定義實現示例中,PdfReportGenerator是作為定義生成PDF報告合約的抽象類,設置為虛擬可選覆寫的方法。 MonthlyReportGenerator是提供每月報告生成的具體實現,通過覆寫虛擬方法自定制設置。

C#虛擬與抽象(開發人員如何使用):圖2 - 報告輸出

結論

C#虛擬與抽象(開發人員如何使用):圖3 - 許可證

有效地理解和使用虛擬和抽象方法可以大大提升您的C#編程。 請記住,抽象方法要求派生類提供實現,而虛擬方法允許可選的覆寫默認實現。 IronPDF庫提供免費試用和許可選項,許可從$799開始,為您的PDF需求提供全面的解決方案。

常見問題解答

什麼是 C# 中的虛擬方法?

C# 中的虛擬方法是包含默認實現的方法,可以由派生類覆蓋以提供特定行為,促進代碼設計的彈性。

如何在 C# 中使用 IronPDF 將 HTML 轉換為 PDF?

您可以使用 IronPDF 的 RenderHtmlAsPdf 方法將 HTML 字符串轉換為 PDF。這使您可以在生成的 PDF 文檔中保持 HTML 內容的佈局和樣式。

C# 中虛擬方法與抽象方法有什麼不同?

虛擬方法有一個默認實現,可以在派生類中選擇性地覆蓋,而抽象方法沒有實現,必須在派生類中覆蓋。

IronPDF 如何幫助生成 .NET 應用程序中的 PDF?

IronPDF 是一個強大的庫,可促進在 .NET 應用程序中生成、編輯和閱讀 PDF 文檔。它允許從 HTML 內容創建 PDF,確保保留佈局。

什麼是 C# 中的抽象方法?

抽象方法是在抽象類中聲明而沒有實現的方法,必須在任何非抽象派生類中實現,以確保派生類的特定行為。

C# 中的類可以同時具有虛擬和抽象方法嗎?

是的,類可以包含虛擬和抽象方法。虛擬方法提供默認實現,而抽象方法需要在派生類中明確實現。

如何在派生類中覆蓋虛擬方法?

要在派生類中覆蓋虛擬方法,需要使用 override 關鍵字繼續該方法的簽名,以實現新的或擴展的實現。

開發人員應該何時使用 C# 中的虛擬方法?

當需要一種默認行為並且可以由派生類選擇性地覆蓋時,開發人員應該使用虛擬方法,以促進多態性和代碼的可重用性。

在 C# 專案中使用 IronPDF 有什麼好處?

IronPDF 通過提供強大的 PDF 生成和操作功能(如將 HTML 轉換為 PDF 以及保持文檔設計完整性)來增強 C# 項目。

IronPDF 如何確保 PDF 文檔的佈局得以保留?

IronPDF 通過精確呈現 HTML 字符串、文件或 URL 為 PDF 格式來轉換 HTML 內容,確保輸出中的所有樣式和佈局都得以保留。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。