C#基礎篇(06)抽象類與接口詳解區別

抽象類是 C# 面向對象編程中的一個重要概念,它介于普通類和接口之間,提供了一種定義部分實現并要求派生類完成其余部分的機制。

一、C# 中的抽象類

抽象類是 C# 面向對象編程中的一個重要概念,它介于普通類和接口之間,提供了一種定義部分實現并要求派生類完成其余部分的機制。

1. 抽象類的基本概念

抽象類是不能被實例化的類,主要用于作為其他類的基類。它通過 abstract 關鍵字聲明:

public abstract class Animal
{// 類成員
}

2. 抽象類的特點

  • ?不能被實例化?:不能創建抽象類的對象
  • ?可以包含抽象成員?:這些成員必須在派生類中實現
  • ?可以包含具體實現?:與接口不同,抽象類可以包含已實現的方法
  • ?可以包含字段、屬性、方法、事件等?:功能比接口更全面
  • ?支持訪問修飾符?:可以控制成員的訪問級別

3. 抽象成員

抽象類可以包含抽象成員(方法、屬性、索引器或事件):

public abstract class Animal
{// 抽象方法(無實現)public abstract void MakeSound();// 抽象屬性public abstract string Name { get; set; }
}

派生類必須實現所有抽象成員:

public class Dog : Animal
{public override void MakeSound(){Console.WriteLine("Woof!");}private string _name;public override string Name {get { return _name; }set { _name = value; }}
}

4. 抽象類與具體類的比較

特性抽象類具體類
實例化不能
包含抽象成員可以不能
包含具體實現可以可以
繼承要求必須實現所有抽象成員無特殊要求

5. 抽象類與接口的比較

特性抽象類接口
實現部分實現無實現
多繼承不支持支持
字段可以包含不能包含
構造函數可以有不能有
訪問修飾符支持默認public
版本控制添加新成員可能破壞派生類添加新成員會破壞實現

6. 何時使用抽象類

  • 當多個相關類共享通用功能,但各自又有獨特行為時
  • 需要提供一些基礎實現,同時要求派生類實現特定功能時
  • 需要包含非公共成員(protected/internal)時
  • 需要定義構造函數、析構函數或靜態成員時

7. 抽象類的實際示例

public abstract class Shape
{// 抽象方法 - 必須被派生類實現public abstract double Area();// 具體方法 - 已實現public void Display(){Console.WriteLine($"Area: {Area()}");}// 抽象屬性public abstract string Color { get; set; }
}public class Circle : Shape
{public double Radius { get; set; }public override string Color { get; set; }public override double Area(){return Math.PI * Radius * Radius;}
}public class Rectangle : Shape
{public double Width { get; set; }public double Height { get; set; }public override string Color { get; set; }public override double Area(){return Width * Height;}
}

8. 抽象類的進階用法

8.1 抽象類中的構造函數

public abstract class Vehicle
{protected string _model;protected Vehicle(string model){_model = model;}public abstract void Drive();
}public class Car : Vehicle
{public Car(string model) : base(model) { }public override void Drive(){Console.WriteLine($"Driving {_model}");}
}

8.2 部分實現的模板方法模式

public abstract class DataProcessor
{// 模板方法public void Process(){ReadData();ProcessData();SaveResult();}protected abstract void ReadData();protected abstract void ProcessData();protected virtual void SaveResult(){Console.WriteLine("Default save implementation");}
}

9. 總結

抽象類是 C# 中實現多態和代碼重用的強大工具,它:

  • 強制派生類實現特定行為
  • 提供共享的基類實現
  • 比接口更靈活,可以包含狀態和行為
  • 適合構建具有層次結構的類家族

正確使用抽象類可以使代碼更加清晰、可維護,并減少重復代碼。

二、C# 中的接口

接口是 C# 中實現多態和抽象的核心機制之一,它定義了一組相關功能的契約,而不提供具體實現。

1. 接口的基本概念

接口使用 interface 關鍵字聲明:

public interface IAnimal
{void MakeSound();string Name { get; set; }
}

2. 接口的特點

  • ?純契約?:只包含成員聲明,不包含實現
  • ?多繼承?:一個類可以實現多個接口
  • ?隱式公開?:所有成員默認是 public 的
  • ?不能包含字段?:只能包含方法、屬性、事件和索引器
  • ?不能有構造函數?:因為不能被實例化
  • ?不能包含靜態成員?(C# 8.0 前)

3. 接口成員的實現

類通過 : 符號實現接口,并提供具體實現:

public class Dog : IAnimal
{private string _name;public void MakeSound(){Console.WriteLine("Woof!");}public string Name {get { return _name; }set { _name = value; }}
}

4. 顯式接口實現

當多個接口有同名成員時,可使用顯式實現:

public class Animal : IAnimal, IDisposable
{void IAnimal.MakeSound(){Console.WriteLine("Animal sound");}void IDisposable.Dispose(){Console.WriteLine("Disposing");}
}

5. 接口與抽象類的比較

特性接口抽象類
實現可以有
多繼承支持不支持
字段不能有可以有
構造函數不能有可以有
版本控制添加成員會破壞實現更靈活
訪問修飾符默認public可控制

6. 接口的默認實現(C# 8.0+)

C# 8.0 引入了接口默認實現:

public interface ILogger
{void Log(string message);// 默認實現void LogError(string error){Log($"Error: {error}");}
}

7. 接口的實際應用示例

7.1 依賴注入

public interface IRepository
{void Save(Customer customer);Customer GetById(int id);
}public class SqlRepository : IRepository
{public void Save(Customer customer) { /* SQL實現 */ }public Customer GetById(int id) { /* SQL實現 */ }
}public class CustomerService
{private readonly IRepository _repository;public CustomerService(IRepository repository){_repository = repository;}public void AddCustomer(Customer customer){_repository.Save(customer);}
}

7.2 策略模式

public interface ISortStrategy
{void Sort(List<int> list);
}public class QuickSort : ISortStrategy
{public void Sort(List<int> list) { /* 快速排序實現 */ }
}public class BubbleSort : ISortStrategy
{public void Sort(List<int> list) { /* 冒泡排序實現 */ }
}public class Sorter
{private ISortStrategy _strategy;public Sorter(ISortStrategy strategy){_strategy = strategy;}public void Sort(List<int> list){_strategy.Sort(list);}
}

8. 接口的高級特性

8.1 接口繼承

接口可以繼承其他接口:

public interface IReadableRepository
{object GetById(int id);
}public interface IWritableRepository : IReadableRepository
{void Save(object entity);
}

8.2 泛型接口

public interface IRepository<T>
{void Add(T entity);T GetById(int id);IEnumerable<T> GetAll();
}

8.3 協變和逆變接口(C# 4.0+)

// 協變(out)
public interface IEnumerable<out T> { /*...*/ }// 逆變(in)
public interface IComparer<in T> { /*...*/ }

9. 接口的使用場景

  1. ?定義跨類別的行為?:如 IDisposable
  2. ?實現多繼承?:一個類可以實現多個接口
  3. ?依賴注入?:通過接口解耦依賴
  4. ?單元測試?:通過接口創建Mock對象
  5. ?插件架構?:定義擴展點
  6. ?策略模式?:定義算法族

10. 接口設計的最佳實踐

  1. ?單一職責?:每個接口應專注于一個特定功能
  2. ?命名規范?:以"I"開頭,如 IEnumerable
  3. ?避免過大接口?:防止實現類負擔過重
  4. ?優先組合而非繼承?:通過多個小接口組合功能
  5. ?考慮向后兼容?:添加新成員可能破壞現有實現

11. 總結

C# 中的接口是:

  • 定義行為契約的強大工具
  • 實現松耦合設計的關鍵
  • 支持多繼承的機制
  • 現代C#中功能不斷增強(默認實現等)

正確使用接口可以使代碼更加靈活、可測試和可維護,是面向對象設計和架構設計中的重要組成部分。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/87922.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/87922.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/87922.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Python將PDF轉換成word、PPT

在現代企業環境中,文檔格式的轉換是一項普遍且關鍵的需求。PDF(Portable Document Format)作為一種最終的、通常不可編輯的“打印”狀態格式,被廣泛用于分發和歸檔。然而,內容的創建、協作和修改主要在Microsoft Office套件中進行,特別是Word(DOCX)和PowerPoint(PPTX)…

香港風水(原生)林地的邏輯分類器

風水林是香港的原生林地&#xff0c;由于地處偏遠、地形崎嶇以及當地居民的信仰&#xff0c;這些林地得以保存完好。在香港&#xff0c;我們可以追溯到1924年的航拍圖像記錄&#xff0c;這些黑白航拍圖像已經幫助我們劃分和區分了林地、草地和灌木叢。然后&#xff0c;通過二戰…

[Swarm] Result對象 | 智能體切換 | Response對象 | muduo review

第5章&#xff1a;結果對象 歡迎回到swarm&#xff01; 在上一章第4章&#xff1a;功能中&#xff0c;我們學習了如何通過定義Python功能賦予智能體技能。我們見證了當AI決策調用時&#xff0c;Swarm框架如何執行這些功能。 當前&#xff0c;我們的功能僅返回簡單字符串如&q…

[2-02-02].第04節:環境搭建 - Linux搭建ES集群環境

ElasticSearch學習大綱 一、ES集群規劃&#xff1a; 關系型數據庫&#xff08;比如Mysql&#xff09;非關系型數據庫&#xff08;Elasticsearch&#xff09;非關系型數據庫&#xff08;Elasticsearch&#xff09;centos7hadoop103192.168.148.3centos7hadoop104192.168.148.4c…

部署并運行Spike-Driven-Transformer或QKFormer

部署并運行Spike-Driven-Transformer或QKFormer 我將指導你如何部署和運行Spike-Driven-Transformer或QKFormer代碼,并在CIFAR-10、CIFAR-100和ImageNet-1K數據集上進行訓練和測試。 1. 環境準備 首先需要設置Python環境并安裝必要的依賴項: # 創建conda環境(推薦) con…

爬蟲-request處理POST

1.概念很少在URL寫參數&#xff0c;都在form data里面POST 的主要作用是將客戶端的數據提交給服務器。這些數據可以是表單輸入、文件內容、JSON 數據、XML 數據等等POST 請求攜帶的數據放在 HTTP 消息的請求體中。這與 GET 請求形成鮮明對比&#xff1a;GET 請求的數據通常附加…

免U盤一鍵重裝系統

免U盤一鍵重裝系統 簡單介紹 詳細的看GitHub項目首頁 GitHub地址 # 下載腳本 curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_ # 重裝系統 bash reinstall.sh ubuntu # 重啟 rebootPS: 重啟過程中, 可能需要手動選擇r…

自動化一次通過率

自動化測試中的“一次通過率”&#xff08;First-pass Pass Rate&#xff09;?? 是指自動化測試腳本在首次執行&#xff08;無人工干預、無重試&#xff09;?時&#xff0c;?成功通過的測試用例數占總執行用例數的百分比。?核心概念解析???“一次”的含義??首次運行?…

111111事件

1.抽取 minio 當做文件對象存儲服務器&#xff0c;在上面封裝一層api&#xff0c;方便操作。 &#xff08;文件上傳&#xff0c;指定路徑上傳&#xff0c;隨機命名上傳&#xff0c;前端獲取token直接傳&#xff0c;適合大對象&#xff0c;圖片壓縮&#xff09; 2.規范整個java項…

Qt的ui文件的編譯和使用

Qt中的ui文件編譯的類 要么繼承 &#xff0c;要么實例化一個變量個人覺得還是繼承好點&#xff0c;這樣每次調用控件時&#xff0c;不用都要在控件前加上 ui.1 上面使用的是繼承的關系&#xff0c;這樣就可以直接使用控件.屬性&#xff0c;而不用 ui.控件.樹形2 QT中UI文件…

數據結構之樹,二叉樹,二叉搜索樹

一.樹1.形狀2. 相關概念節點的度&#xff1a;一個節點含有的子樹的個數稱為該節點的度&#xff1b; 如上圖&#xff1a;A的為6葉節點或終端節點&#xff1a;度為0的節點稱為葉節點&#xff1b; 如上圖&#xff1a;B、C、H、I...等節點為葉節點非終端節點或分支節點&#xff1a;…

LLM微調隨記錄

【如何把領域文獻批量轉換為可供模型微調的數據集&#xff1f;】 https://www.bilibili.com/video/BV1y8QpYGE57/?share_sourcecopy_web&vd_source8f9078186b93d9eee26026fd26e8a6ed 幾個問題 首先要先搞清楚這幾個問題 LLM 訓練方法如何選擇合適的訓練方式如何判斷是否…

高效處理大體積Excel文件的Java技術方案解析

高效處理大體積Excel文件的Java技術方案解析 引言 在數據密集型應用中&#xff0c;處理數百MB甚至GB級的Excel文件已成為業務剛需。傳統基于DOM模型的Excel解析方式&#xff08;如Apache POI的XSSF&#xff09;在處理大規模數據時存在嚴重的內存瓶頸。本文將深入探討Java生態中…

JVM垃圾回收機制深度解析

&#x1f5d1;? JVM垃圾回收機制深度解析 文章目錄&#x1f5d1;? JVM垃圾回收機制深度解析&#x1f50d; 垃圾判定算法&#x1f522; 引用計數法&#x1f310; 可達性分析算法&#x1f504; 垃圾回收算法&#x1f3f7;? 標記-清除算法&#x1f4cb; 復制算法&#x1f527; …

Docker:容器化技術的基石與實踐指南

在現代軟件開發和部署中&#xff0c;Docker 作為一種領先的容器化平臺&#xff0c;已經成為了開發人員和運維工程師不可或缺的工具。它不僅簡化了應用的部署過程&#xff0c;還提高了應用的可移植性和可擴展性。本文將深入探討 Docker 的核心概念、基本操作以及如何在實際項目中…

java web7(黑馬)

Filter簡介概念: Filter 表示過濾器&#xff0c;是 JavaWeb 三大組件(Servlet、Filter、Listener)之一。過濾器可以把對資源的請求攔截下來&#xff0c;從而實現一些特殊的功能。過濾器一般完成一些通用的操作&#xff0c;比如:權限控制、統一編碼處理、敏感字符處理等等.快速入…

React-forwardRef-useImperativeHandle

forwardRef 暴露dom節點作用&#xff1a;使用ref暴露DOM節點給父組件案例例如在父組件中想要獲取子組件input的輸入值&#xff0c;和讓input獲取焦點父組件import { Button } from antd-mobile import Son from "./components/son"; import { useState,useRef } fro…

Unity 用AI自動開發游戲----Cursor研究(實現一套利用Cursor生成模板快速實現原型的框架)

Unity 快速原型開發框架&#xff08;基于 Cursor AI&#xff09; &#x1f9e9; 框架簡介 本框架結合了 AI 編程助手 Cursor 的代碼生成能力&#xff0c;構建出一套適用于 Unity 項目的模塊化原型開發架構。它旨在極大提升開發效率、降低試錯成本&#xff0c;特別適用于快速搭…

D觸發器實現2分頻verilog及電路

使用D觸發器完成2分頻電路即通過時鐘的上升沿或下降沿到來時進行翻轉得到&#xff0c;信號的兩個狀態所占時間長度相同&#xff0c;因此它的輸出時鐘的占空比為50%。 D觸發器實現2分頻的電路圖如下所示&#xff1a;通過將D觸發器2分頻電路級聯&#xff0c;可實現輸入時鐘的2N倍…

UniApp完美對接RuoYi框架開發企業級應用

UniApp完美對接RuoYi框架的完整方案及可開發系統類型&#xff0c;結合企業級實踐與開源項目經驗整理而成&#xff0c;涵蓋技術對接、系統設計及實戰案例。 &#x1f527; 一、UniApp與RuoYi對接全流程 1. 后端配置&#xff08;RuoYi-Vue/RuoYi-Cloud&#xff09; 跨域支持 在網…