跳至頁尾內容
開發者更新

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,則提供了一種預設的啟動引擎的方法,若有需要,繼承的類別可以覆寫。

派生類別範例

現在,讓我們定義一個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

在這個範例中,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程式庫提供免費試用和授權選項,授權起價從$999開始,為您的PDF需求提供全面的解決方案。

常見問題

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

在C#中,虛擬方法是包含預設實作的方法,但可以被派生類覆寫以提供特定行為,促進程式碼設計的靈活性。

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

您可以使用IronPDF的RenderHtmlAsPdf方法將HTML字串轉換為PDF。這樣可在結果PDF文件中保留HTML內容的佈局和樣式。

C#中的虛擬方法與抽象方法有何不同?

虛擬方法有預設實作並可選擇性地在派生類中被覆寫,而抽象方法沒有實作,必須在派生類中被覆寫。

IronPDF如何協助.NET應用程式生成PDF?

IronPDF是一個強大的程式庫,可以在.NET應用程式中生成、編輯和讀取PDF文件。它允許從HTML內容建立PDF,確保佈局得以保留。

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

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

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

是的,一個類可以同時包含虛擬方法和抽象方法。虛擬方法提供預設實作,而抽象方法要求在派生類中具體實作。

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

要在派生類中覆寫虛擬方法,您可以使用override關鍵字後接方法簽名,以允許新或擴展的實作。

開發者應何時在C#中使用虛擬方法?

當需要預設行為,可以由派生類選擇性地覆寫時,開發者應使用虛擬方法,以促進多態性和程式碼重用。

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

IronPDF通過提供強大的PDF生成和操作功能來增強C#專案,例如將HTML轉換為PDF並保持文件的設計完整性。

IronPDF如何確保PDF文件佈局的保留?

IronPDF通過準確渲染HTML字串、文件或URL到PDF格式,確保輸出中保留所有樣式及佈局。

Jacob Mellor,首席技術官 @ Team Iron
首席技術官

Jacob Mellor是Iron Software的首席技術官,一位在C# PDF技術上開創先河的遠見工程師。作為Iron Software核心程式碼庫的原開發者,他從創立以來就一直在塑造公司的產品架構,與首席執行官Cameron Rimington一起將公司轉變為服務於NASA、特斯拉和全球政府公司的50多名人員的公司。

Jacob擁有曼徹斯特大學的土木工程一等榮譽學士學位(BEng),於1998-2001年之間獲得。在1999年於倫敦創辦他的第一家軟體公司並於2005年建立了他的第一批.NET元組件後,他專注於解決Microsoft生態系統中的複雜問題。

他的旗艦IronPDF和Iron Suite .NET程式庫在全球獲得了超過3000萬次NuGet安裝依據,他的基礎程式碼基繼續支援著世界各地開發者使用的工具。擁有25年的商業經驗和41年的程式設計專業知識,他仍專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話