假設,班級里40位同學,我們用程式保存40位學生的信息:學號,姓名,性別,生日,身份證號。如果是你,你會怎麼實現? 小菜同學拿到這個題,奮書疾筆,馬上寫出如下代碼: ArrayList list = new ArrayList(); string stuNo1="10001"; string n ...
小菜同學拿到這個題,奮書疾筆,馬上寫出如下代碼:
ArrayList list = new ArrayList(); string stuNo1="10001"; string name1 = "張三"; string sex="男"; Datetime birthday1 = Datetime.Parse("1998-08-08"); string idCard1 = "362530199808080510"; list.add(stuNo1); list.add(name1); ... list.add.... ........//經過1個半小時後,終於到了第40位。
那如果是有4000,4萬?你是不是立馬從入門到卸載了?面向對象來告訴你解決方案!!
1. 面向對象概念
面向對象編程( OOP,Object Oriented Programming
)
-
並不是一個技術,而是一種編程指導思想。
-
把現實世界的具體事物全部看成一個一個的對象來解決實際問題。
為什麼要用面向對象編程
生活中我們解決問題就是按照對象化的方式進行的。如果程式也能夠按照生活的中的方式來解
決問題,那麼程式就更符合人類的思維習慣,代碼看起來會更易理解、更簡單、更易維護。
面向對象編程共同三大特性:封裝,繼承,多態。
在C# 中,一定要時刻的牢記這句話:一切皆為object(對象);
2. 封裝
封裝 被定義為"把一個或多個項目封閉在一個物理的或者邏輯的包中"。在面向對象程式設計方法論中,封裝是為了防止對實現細節的訪問。
抽象和封裝是面向對象程式設計的相關特性。抽象允許相關信息可視化,封裝則使開發者實現所需級別的抽象。
訪問修飾符
C# 封裝根據具體的需要,設置使用者的訪問許可權,並通過 訪問修飾符 來實現。
一個 訪問修飾符 定義了一個類成員的範圍和可見性。C# 支持的訪問修飾符如下所示:
-
public:所有對象都可以訪問;
-
private:對象本身在對象內部可以訪問;
-
protected:只有該類對象及其子類對象可以訪問
-
internal:同一個程式集的對象可以訪問;
-
protected internal:訪問限於當前程式集或派生自包含類的類型。
實現封裝的方式共有三種:類的封裝,屬性封裝,方法的封裝。
封裝的作用:
-
隱藏細節,設置訪問許可權,提高安全性
-
代碼復用。
-
提高代碼的可讀性
3. 什麼是類
類是一組具有相同事物和行為的抽象(物以類聚)。
類在實現生活中是不存在的,看不見,摸不著。例如:人類,狗類,貓科類,靈長類.... 這些事物都只是一些抽象的概念,並不是指具體的物體。如果我說:小明今天吃了三碗飯,小紅的頭髮很長,那麼,小明,小紅 是指人類的具體對象,lucky(一隻貓) 這個月身體長得很快,這也指的是對象,因為lucky是實實在在存在的。
人為什麼不和狗分為一類?
答:因為人和狗的體徵行為都不一樣!!再次強調類:類是一組具有相同事物和行為的抽象(物以類聚)。人會思考,人會製作工具,而狗不會。
對象:是真實存在的具體實例。
類(設計圖):是對象共同特征的描述(抽象)。
在C#中,必須先設計類,才能獲得對象。
4. 如何定義類
定義類的關鍵字是class,命名規範為首字母大寫,以帕斯卡(大駝峰)方式命名 如:
<訪問修飾符> class 類名 { // 構造器(下一個單元會講到) // 欄位 // 屬性(特征) // 方法(行為) // 事件(C# 高級階段學習) // 索引器(c# 高級階段學習) }
如:
public class Person { // 欄位 private string name; // 屬性 public string Name { get { return name; } set { value=name; } } // 方法 public void eat() { Console.WriteLine("吃飯,我要吃油燜大蝦"); } }
其中,欄位,屬性,方法,被統稱為類的成員。欄位,屬性 被稱為成員變數,方法被稱為成員方法。
訪問標識符 <access specifier> 指定了對類及其成員的訪問規則。如果沒有指定,則使用預設的訪問標識符。類的預設訪問標識符是 internal,成員的預設訪問標識符是 private。
5. 欄位與屬性
欄位一般是私有的(private),屬於類的私有信息,如:姓名,年齡,身份證號等等信息都是屬於人類的私有信息。
public class Person { private string name; private int age; }
屬性是類對外提供訪問欄位的途徑,一般是公有的(public) ,如:別人問你年齡,女孩子一般說18歲。此時她說的18歲是她自己對外主動暴露出來的,事實上她的真實年齡信息是私有的,只有她自己知道,到底是不是18歲我們其實是不清楚的。
public class Person { private string name; private int age; public string Name { // get 訪問器 get { return name; } // set 訪問器 set { value=name; } } public int Age { get { return 18; } set { value = age; } } }
Get, Set 訪問器都可以設置訪問修飾符哦,預設的訪問修飾符都是public.
c# 9.0 之後 還支持
Init
訪問器, 調用方可使用屬性初始化表達式語法 , 在創建表達式中設置這些值 。 但構造完成後,這些屬性將變為只讀
欄位與屬性的區別
-
欄位是私有的(private),屬性是公開的(public)。
-
屬性具有讀寫器( get, set)
-
欄位命名,以小駝峰命名,屬性以帕斯卡(大駝峰)命名。
-
屬性並沒有真正存儲數據
只讀屬性
也就是只提供了, Get 訪問器,沒有Set 訪問器。
public class Person { private short orderState public string OrderState { get { switch(orderState){ case 1: return "待支付"; case 2: return "待發貨"; case 3: return "待收貨"; case 4: return "已完成"; default: return "待支付"; } } } }
只寫屬性
也就是只提供了, Set 訪問器,沒有Get 訪問
public class Person { private string pwd public string Password { set { value = pwd;} // 沒有Get } }
屬性簡寫
如果一個類中,屬性只是直接對欄位進行讀寫,那麼,這個屬性欄位就可進行簡寫。
例如:
public class Person { private string name; private int age; public string Name { get { return name; } set { value=name; } } public int Age { get { return 18; } set { value = age; } } } // 簡化後 public class Person { public string Name {get; set;} public int Age {get; set;} }
我們剛說過,屬性是對欄位的封裝,但是簡寫後的屬性根本就看不到類,豈不是自相矛盾嗎?其實簡寫屬性中其實隱藏了欄位,如果通過反編譯工具編譯 MS IL 或者通過反射技術去查看,我們會可以將它隱藏的欄位讀取出來。
6. 類的對象(實例)
語法:
類名 對象名 = new 類名(); 如: Person per = new Person();
使用對象
訪問屬性: 對象名.成員屬性 訪問行為: 對象名.方法名(…)
例如:
public class Person { private string name public string Name { set { value = name;} get { return name;} } public void Eat() { Console.WriteLine($"姓名:{name},他正在吃飯.."); } } class Program { static void Main(string[] args) { Person per1 = new Person(); per1.Name = "張三"; // 訪問屬性 per1.Eat(); // 調用成員方法 Person per2 = new Person(); per2.Name = "李四"; // 訪問屬性 per2.Eat(); // 調用成員方法 } }
輸出結果:
姓名:張三,他正在吃飯.. 姓名:李四,他正在吃飯..
7. 構造方法
學構造方法的目的?
-
真正知道對象具體是通過什麼得到的。
-
能夠掌握為對象賦值的其他寫法。
構造方法的作用
-
用於初始化一個類的對象,並返回對象的地址。
-
簡化對象初始化的過程
語法
修飾符 類名(形參列表) { ... } public class Car { ... // 無參數構造器 public Car() { ... } // 有參數構造器 public Car(String n, String b) { ... } }
初始化對象的格式
類名 對象名稱 = new 構造器; Car c = new Car();
構造器的分類
-
無參數構造器(預設存在的):初始化的對象時,成員變數的數據均採用預設值。
-
有參數構造器:在初始化對象的時候,同時可以為對象進行賦值。
註意事項
-
任何類定義出來,預設就自帶了無參數構造器,寫不寫都有。
-
一旦定義了有參數構造器,無參數構造器就沒有了,此時就需要自己寫一個無參數構造器了。
public class Car { ... // 無參數構造器(預設存在的) } public class Car { ... public Car() { // 無參數構造器(需要寫出來了) } public Car(String n, String b) { // 有參數構造器 } }
8. 兩個變數指向同一個對象
class Student { public string Name { get; set; } public string Sex { get; set; } public string Hobby { get; set; } public void Study() { Console.WriteLine($"姓名:{Name},性別:{Sex},愛好:{Hobby}"); } } public static void main(String[] args) { Student s1 = new Student(); s1.Name = "小明"; s1.Sex = '男'; s1.Hobby = "游戲、睡覺、聽課"; s1.Study(); // 把學生類型的s1變數賦值給學生類型的s2變數 Student s2 = s1; s2.Hobby = "愛提問"; Console.WriteLine(s2.Name); Console.WriteLine(s2.Sex); Console.WriteLine(s1.Hobby); s2.Study(); }
輸出結果:
姓名:小明,性別:男,愛好:游戲、睡覺、聽課 小明 男 愛提問 姓名:小明,性別:男,愛好:愛提問
記憶體分佈圖
思考:如果某個對象,被當作方法參數傳遞之後,在方法體內對象(形參)的某些屬性被修改,那麼實參對象的屬性會發生變化嗎?
9. this 關鍵字
假設有如下一段代碼:
public class Person { private string name; private string age; public Person(string name,string age) { name = name; // 此處很有可能會有問題!! age = age; // 此處很有可能會有問題!! } }
編譯器很有可能分不清 name 到底是形參還是成員變數,怎麼破? this 關鍵字就可以幫忙解決。
this關鍵字
-
this關鍵字可以出現在成員方法、構造器中,代表當前對象的地址。
-
作用:訪問當前對象的成員變數、成員方法。
public class Person { private string name; private string age; public Person(string name,string age) { this.name = name; this.age = age; } }
10 . 作業
-
學生類:
-
欄位:姓名,性別,成績,零錢
-
屬性:姓名:性別,成績( 只寫Set訪問器),成績等級(成績<60 -->差,60<= 成績<= 70 ---> 一般,70< 成績<=80 --->中,80<成績 <=90--->良, 其他---->優, 並且此屬性只讀),零錢
-
重載構造方法,無參,有參(姓名,性別,成績,零錢)
-
-
學生類中定義Print 方法,將 姓名,性別,成績,零錢等級 輸出到控制台。
-
在學生類中,定義
HelpShop()
方法,意思是 學生可以幫其他同學購物,然後自己獲得同學給的1元的佣金。偽代碼如下:public class Student { // ...欄位 // ...屬性 /// <summary> /// 幫其他同學購物 /// <summary> /// <param name="s">被幫助的同學</param> /// <param name="money">購物所花費的金額</param> public void HelpShop(Student s, decimal money) { } }
-
在Main方法中創建學生類對象,通過無參構造方法創建
s1
對象,然後給 姓名,性別,成績,零錢 屬性賦值。 -
在Main方法中創建學生類對象,通過有參構造方法創建
s2
對象 並初始化對象。 -
調用
s1, s2
Print方法,查看屬性值。 -
s1
調用HelpShop
方法, 將s2
作為參數傳遞進去 -
再次調用Print 方法,查看
s1, s2
的屬性值的變化。
視頻教程:
譽尚學教育_譽尚學教育騰訊課堂官網 (qq.com)
或者:C# 最強入門編程(.Net 學習系列開山巨作)_嗶哩嗶哩_bilibili
海闊平魚躍,天高任我行,給我一片藍天,讓我自由翱翔。