c#基礎二(類和對象,構造器調用順序、訪問級別、重寫和多態、抽象類和接口)

一、類

1.0對象初始化器

class Student
{public String name;public int age { get; set; }
}
internal class Program
{static void Main(string[] args){  //寫法一Student stu=new Student();stu.name="Tom";stu.age=20;//寫法二Student stu2 = new Student { name = "Tom", age = 20 };

在 C# 中,?Student stu2 = new Student { name = "Tom", age = 20 }中的?{}?稱為對象初始化器(Object Initializer),它是 C# 3.0 引入的語法糖,用于在創建對象時使用鍵對值方式直接初始化對象的公共屬性或公共字段,簡化代碼書寫,等同于寫法一;

1.1構造器(構造函數)

特點:

與類同名,沒有返回值

不自己定義系統會生成一個默認的構造器,就是將給成員屬性賦該類型默認值

自己定義默認構造器會被覆蓋,而不是重載(因為無法再調用系統自動生成的構造器)

1.1.1實例構造器和靜態構造器

靜態構造器不能有修飾限定符

靜態構造器不能有參數

靜態構造器不能重載

 class student{public int score { get; set; }public static int num { get; set; }//實例構造器public student(int score){this.score = score;num++;}//靜態構造器static student(){num = 100;}}

1.1.2實例構造器和靜態構造器的調用時機

實例構造器
  1. 每次使用?new?關鍵字創建類的實例時,必然會調用實例構造器(如果有多個重載,會根據new?后的參數匹配對應的構造器)。
  2. 類有繼承關系,創建派生類實例時,會先調用基類的實例構造器,再調用派生類的實例構造器(確保基類的實例成員先初始化)
靜態構造器

靜態構造器是類被首次 “訪問” 時自動調用的方法,用于初始化類的靜態成員(靜態字段、靜態屬性等),與實例無關

  1. 首次創建該類的實例new實例時)。
  2. 首次訪問該類的靜態成員(靜態字段、靜態屬性、靜態方法)。
  3. 首次使用該類作為泛型類型參數(如?List<MyClass>?首次被使用時,若?MyClass?未初始化則觸發其靜態構造器
  4. 類有繼承關系,基類的靜態構造器先于派生類的靜態構造器執行

1.2析構器(析構函數)

不加修飾限定符,使用(~類名)方式來定義函數

c#有資源回收器(GC),但是調用底層資源時有用

2、類的聲明

c#類的聲明和定義不分家

聲明位置

  1. 把類聲明在名稱空間中
  2. 也可以把類聲明在文件的名稱空間外,但是c#有一個global名稱空間,因此也在名稱空間內部(不推薦)
  3. 可以聲明在類中(成員類)

3、類的繼承和類成員的訪問控制

“是一個”規則:父類引用變量可以存儲子類實例的地址,含義為:car是一個vehicle? ?

   static void Main(string[] args){vehicle v = new car();object o = new vehicle();object o1 = new car();      }}class vehicle
{}
class car : vehicle
{}
  • sealed關鍵字:封閉類,不能當作基類來使用,下例:編譯器報錯
  • 一個類只能繼承一個基類
  • 一個類可以實現多個基接口
  • 子類的訪問級別不能超過基類
  • 父類的構造器是不能被繼承的

3.2編譯器的調用規則

當創建子類實例時,父類的構造器先被啟動,作用是初始化子類中繼承的屬性的值,下例中我們可以看到car中沒有對owner進行賦值,但是任然可以輸出值vehicle,而如果子類構造器對他賦值了,那么會覆蓋這個結果。

    static void Main(string[] args){car mycar = new car();Console.WriteLine(mycar.owner);   }
}class vehicle
{   public vehicle() { this.owner = "vehilce";}public string owner { get; set; }}
class car : vehicle
{public car(){    }
}

上例是父與子類構造函數無需參數情況,需要參數時需要使用base關鍵字,下例

 class vehicle
{   public vehicle(string own) { this.owner = own;}public string owner { get; set; }}
class car : vehicle
{public car(string own):base(own){  }
}

3.3類的訪問級別和類成員的關系

類成員的訪問級別的上限是類的訪問級別

類的默認訪問級別是internal,成員的默認訪問級別是private

protected:是可以跨程序集的,也就是說實際上,四種訪問級別并不是嚴格的大小關系

3.4類的重寫和多態

重寫就是對父類成員的版本更新

重寫需要父類成員對子類是可見的,即不能為private

需要重寫的父類類成員(字段除外),要加關鍵字virtual(標識為可重寫),子類類成員要加override

注意:我們使用父類的引用變量指向了子類的實例,這個方法調用的版本是由子類實例來決定的,在這時調用的重寫的方法是繼承鏈上最新的(到這個類),這就是多態,下例中將car的實例給到父類的引用變量,調用的是繼承鏈到car的最新函數。

    static void Main(string[] args){vehicle c = new car();c.run();//運行結果為:I am driving}
}class vehicle
{public virtual void run(){Console.WriteLine("I am running");}
}
class car : vehicle
{   public override void run(){Console.WriteLine("I am driving");}
}
class racecar : car
{public override void run(){Console.WriteLine("I am racing");}
}

3.5類的組合

在類的繼承中,我們提到了”是一個“原則,即car是子類,vehicle是父類,那么car是一個vehicle,同時父類引用變量可以指向子類的實例;類的組合是”有一個“原則,一個類完全可以將另一個類作為自己的屬性。

舉個栗子:

 class people {public Address address { get; set; }}class Address { public string city { get; set; }}internal class Program{static void Main(string[] args){   //分別實例化兩個類people p=new people();Address a = new Address { city = "New York" };p.address = a;Console.WriteLine(p.address.city);//簡化寫法people p2 = new people { address=new Address { city="AAA" } };Console.WriteLine(p2.address.city);}}

上面代碼定義了兩個類,people這個類直接使用Address作為他的屬性,在我們給people這個類賦值的時候,有兩種方式:

方式一:分別實例化兩個類,將a這個Address類的引用變量賦值給p.address。

方式二:直接嵌套兩個初始化器,在people的初始化器中給address創建一個實例,并且也使用初始化器。

二、抽象類和開閉原則

抽象類

含有抽象方法的類叫做抽象類(只要有一個就行),抽象類和抽象方法要用abstract來修飾,抽象類不能被實例化

抽象方法是指沒有方法體的方法,抽象方法不能是private的,沒有意義

開閉原則

應該將固定的,穩定的成員封裝,不確定的成員應該聲明為抽象成員,留給子類實現

實例:

  • 類和方法都要加abstract
  • 對抽象方法的重新也要加override
  • 抽象類無法創建實例
 abstract class vehicle
{public abstract void run();
}
class car : vehicle
{   public override void run(){Console.WriteLine("car am driving");}
}

三、接口

  • 接口使用interface來定義,類似于類的class,接口本身的訪問修飾符是可以定義的
  • 接口的成員的訪問修飾符固定為public的,不需要寫,也不允許寫
  • 在抽象類和抽象函數中,我們需要加上abstract來修飾這是一個抽象類(函數),但是接口不能寫,直接就是最簡單的函數寫法,下例
  • 接口的方法不行全部被實現,如果一個類實現了接口但是沒有實現全部方法,也就是說內部有抽象方法,這個類是抽象類(符合定義),在繼承鏈上想要實例化一個類,那么這個類肯定是這個抽象類的子孫類
   interface Iphone{void Dail();void Pickup();void Send();void Receive();}class Nokia : Iphone{public void Dail(){Console.WriteLine("Nokia is dailing");}public void Pickup(){Console.WriteLine("Nokia is picking up");}public void Receive(){Console.WriteLine("Nokia is receiving");}public void Send(){Console.WriteLine("Nokia is sending");}}class userphone{private Iphone _phone;public userphone(Iphone phone){_phone = phone;}public void Usephone() { _phone.Dail();_phone.Pickup();_phone.Send();_phone.Receive();}}internal class Program{static void Main(string[] args){userphone user = new userphone(new Nokia());}}

在這個例子中,我們可以看到雖然無法創建接口的實例,但是可以創建接口類型的引用變量指向子類實例實現多態,在userphone中調用Nokia類中函數

如果再有一個另外品牌的手機我們只需要修改傳入的實例即可,例如:(new huawei()),這樣我們可以通過

3.2依賴反轉

由這張圖解釋上面代碼

不使用接口時:

例如:有兩個品牌的手機(Nokia和huawei)需要創建兩個類(這一步都一樣),手機的使用者(userphone)需要使用不同的手機(在這個類中調用手機類的方法)那么要不然就是創建兩個(userphone)類似的類分別實例化,要不只能在一個類中寫兩個不同名的方法(不同點1),這時,手機和手機的使用者,是手機使用者依賴于手機,因為需要在手機使用者方法(Usephone)中實例化手機類才能調用手機中的方法(不同點2)對應圖中左上角

使用接口時:

我們創建一個接口(Iphone),兩個品牌的手機依賴于Iphone因為實現接口,使用者(userphone)依賴于(Iphone),這時依賴關系發生了變化,并且現在在使用者(userphone)中想要實現不同手機類中的方法,只需要使用接口類的引用類型,當實例時傳入Nokia時調用Nokia的方法,傳入huawei時調用huawei的方法

使用接口的優勢:

當我們需要增加一個手機品牌例如三星,不使用接口時,除了寫上三星類,我們需要修改手機使用者類,增加函數,或者直接專門寫一個三星手機使用者的類,對應上圖左上角

使用接口時:只需要寫上三星類,然后調用時把三星類的實例作為實際參數傳給使用者類中的函數的接口的引用變量就可以了(對應上圖右上角)

在修改代碼時不需要改變userphone類的成員,因為userphone不依賴于某個手機品牌的類,只依賴于接口,這樣增加了類的獨立性,我們稱為解耦合

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

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

相關文章

Qt之快捷鍵、事件處理、自定義按鍵——完成記事本項目

快捷鍵我們電腦中的記事本中還支持快捷鍵&#xff0c;如“CTRLO”打開文件、“CTRLS”保存文件在Qt中使用QShortcut這個類創建快捷鍵在.cpp文件的構造函數中創建QShortcut對象&#xff0c;綁定打開文件和保存文件的槽函數放大縮小字體還是在.cpp的構造函數中編寫代碼Widget::Wi…

Open cascade中如何使用BRepAlgoAPI_Splitter分割一個Face

理論介紹 在OpenCASCADE幾何建模內核中&#xff0c;BRepAlgoAPI_Splitter是一個強大的工具&#xff0c;用于將一個形狀&#xff08;Shape&#xff09;用另一個形狀&#xff08;Tool&#xff09;進行分割。這種操作在CAD建模中非常常見&#xff0c;比如用平面切割實體、用曲線分…

【醫療 AI】Baichuan-M2 醫療大模型:技術解讀與使用方法

【醫療 AI】Baichuan-M2 醫療大模型&#xff1a;技術解讀與使用方法1. Baichuan-M2 醫療大模型簡介1.1 基本信息1.2 下載地址1.3 技術特點2. Baichuan-M2 模型技術報告2.1 摘要2.2 醫學性能評估2.2.1 HealthBench基準2.2.2 中國醫療場景對比評估2.3 系統架構2.3.1 驗證器系統2.…

unity pcd 二進制版 簡單顯示文件對象(單色)

unity Point Cloud Viewer and Tool 那個插件不支持pcd二進制&#xff0c;而且網上到處都是AI 我恨這種AI濫用&#xff0c;提供不了一點價值 好了&#xff0c;言歸正傳 可以在Point Cloud Viewer and Tool這個插件報錯地方轉用這個代碼&#xff0c;具體咋結合請自行研究。 …

強大的開源文檔問答工具-Kotaemon

Kotaemon 是一個基于 RAG&#xff08;Retrieval-Augmented Generation&#xff09;架構的開源文檔問答工具&#xff0c;為用戶提供與文檔對話的智能交互體驗。該項目同時服務于終端用戶和開發者&#xff0c;具有高度的可擴展性和定制化能力。技術棧分析核心技術棧后端框架Pytho…

區塊鏈:搭建簡單Fabric網絡并調用智能合約

使用docker服務搭建Hyperledger/fabric網絡的詳細教程&#xff0c;實現構建多節點的簡單聯盟鏈&#xff0c;并編寫、調用智能合約實現投票業務。 目錄 背景知識 Hyperledger Fabric 基本組件 交易(Transaction) 智能合約 實驗目的 實驗環境 基礎依賴 安裝Golang 安裝do…

Web前端面試題(2)

Web前端面試題(附答案及解析)&#xff08;2025.9月最新版&#xff09;-CSDN博客 1.link 與 import 的區別和用法 主要區別 特性<link>import語法類型HTML標簽CSS規則加載方式并行加載&#xff08;與其他資源同時加載&#xff09;串行加載&#xff08;必須等待主CSS文件…

Paxos協議

目錄 Paxos 是什么&#xff08;What&#xff09; Paxos 的目的&#xff08;Why&#xff09; 角色與職責&#xff08;Who&#xff09; 基本流程&#xff08;How&#xff09; 常見問題與對策 什么是多數派&#xff08;Quorum&#xff09; Paxos vs Raft 異同點 Paxos 是什…

第十二篇:Qcom Camx打印實時幀率 FPS

一、第一種方式(有些低平臺可能沒有) adb shell setprop persist.vendor.camera.enableFPSLog TRUE adb shell setprop persist.vendor.camera.systemLogEnable TRUE adb shell setprop vendor.debug.camera.overrideLogLevels 0xff chi-cdk/core/chiframework/chxextensi…

TRAE通用6A規則+敏捷開發5S規則

網上研究別人的一些規則,也搞一份給大家 6A工作流項目規則 身份定義 你是一位資深的軟件架構師和工程師,具備豐富的項目經驗和系統思維能力。你的核心優勢在于: 上下文工程專家:構建完整的任務上下文,而非簡單的提示響應 規范驅動思維:將模糊需求轉化為精確、可執行的規…

【Nginx開荒攻略】Nginx主配置文件結構與核心模塊詳解:從0到1掌握nginx.conf:

目錄 引言 1 nginx.conf的整體結構 2 main全局塊詳解 2.1 核心指令解析 2.1.1 user&#xff1a;運行用戶 2.1.2 worker_processes&#xff1a;工作進程數 2.1.3 pid&#xff1a;PID文件路徑 2.1.4 worker_rlimit_nofile&#xff1a;文件描述符限制 2.2 main塊配置示例…

【前端教程】從基礎到優化:一個登錄頁面的完善過程

最近做了一個簡單的登錄頁面,主要練習了文本框的onfocus與onblur事件的使用。雖然功能實現了,但仔細想想還有不少可以改進的地方。今天就來分享一下這個登錄頁面的開發過程和優化思路。 初始實現與解析 先來看一下最初的實現代碼: <!DOCTYPE html> <html> &l…

獨家 | 抖音生活服務調整:涂晴接管市場和達人運營,旭凱擔任北部大區負責人

文/刀客doc(頭條精選作者)刀客doc獨家獲悉&#xff0c;9月8日抖音生活服務完成新一輪組織調整&#xff0c;并已在內部all hands完成官宣。此次調整主要涉及北部大區、達人運營與市場部三大條線的人事輪換與匯報關系變更。核心變動如下&#xff1a;涂晴&#xff0c;原抖音生活服…

class_9:java 抽象類和接口

抽象類 需要用abstract 修飾類和接口abstract class Person{String address;String name;abstract public void eat();abstract public void drink();public void printInfo(){System.out.println("name " name);}} class Student extends Person{public void eat()…

【C++】隊列queue的使用

語法 在 C 中&#xff0c;隊列的語法如下&#xff1a; #include <queue>// 聲明隊列 std::queue<Type> q;這里 Type 是隊列中存儲元素的數據類型。 常用操作 隊列提供了以下常用操作&#xff1a; empty(): 檢查隊列是否為空。 size(): 返回隊列中的元素數量。 fron…

HTTP 協議的基本格式

目錄 &#xff08;一&#xff09;HTTP是什么 &#xff08;二&#xff09;報文格式 &#xff08;1&#xff09;請求 ①首行 1.URL 2.方法&#xff08;method&#xff09; Ⅰ.GET Ⅱ.POST Ⅲ.PUT Ⅳ.DELETE 3.版本號 ②請求頭&#xff08;header&#xff09; 1.鍵值對…

計算機網絡的基本概念-2

1、數據交換技術&#xff1a;電路交換、報文交換與分組交換網絡核心部分的關鍵設備是路由器&#xff0c;其工作方式是分組交換。要理解分組交換&#xff0c;必須先了解其前兩種技術。1. 電路交換 (Circuit Switching)核心思想&#xff1a;通信前必須預先建立一條專用的物理通路…

車載網絡技術--SOME_IP協議詳解

文章目錄前言SOME/IP概念SOME/IP協議格式SOME/IP功能介紹序列化序列化規則發布和訂閱服務發現&#xff08;SOME/IP-SD&#xff09;SOME/IP-TP協議使用場景SOME/IP-TP協議參考文章&#xff1a;前言 本文介紹了SOME/IP協議的具體內容&#xff0c;包括報文格式&#xff0c;協議選…

JVM 核心知識全解析:從類加載到垃圾回收的深度認知

什么是JVM&#xff1f; JVM全稱&#xff08;Java Virtual Machine&#xff09;&#xff0c;中譯為&#xff1a;Java虛擬機 本質&#xff1a;是一個運行在計算機上的程序 職責&#xff1a;運行Java字節碼文件&#xff08;因為計算機只能認識機器碼文件&#xff0c;所以需要JVM將…

Keepalived 負載均衡

Keepalived 負載均衡 Keepalived 可以與 LVS&#xff08;Linux Virtual Server&#xff09;結合&#xff0c;提供強大的四層負載均衡功能。它通過 IPVS&#xff08;IP Virtual Server&#xff09;內核模塊實現高性能的負載分發。 核心組件 Virtual Server&#xff1a;虛擬服務器…