標籤:led double c# interface virtual 名稱 分類 false 簽名
一:物件導向的基本知識
C#程式分為面向過程和物件導向
什麼是對象:一切皆為對象:Object,生活中常說的“東西”就是程式裡面所指的對象;生活中遇到的東西我們都在下意識的歸類;歸類意味著抽象模型;
類:class,對某類眾多個物件的共同特點抽象出來的模型。
他們的關係:類是好多個物件的抽象,對象是類的執行個體化。
建立一個名為Dog的類:
class Dog //一般首字母大寫 { int age; public void setage(int a) //用方法賦值 { age = a; } public void buck() { Console.WriteLine("這是一個方法"); } }
類中一般包括兩類東西,變數(名詞,也交成員變數這裡age是成員變數)和函數(動詞,也叫成員函數或成員方法 buck()就是方法)。
對象執行個體化:
Dog d1 = new Dog();
這樣就執行個體化出了一個Dog的對象a。
例子:兩個套在一起的圓,求內圓的周長和內圓與外圓之間的面積,用物件導向的思想做
class circle { float r; public circle(float a) { r = a; } public double zhouchang() { return 2 * 3.14 * r; } public double mianji() { return 3.14 * r * r; } } class Program { static void Main(string[] args) { circle m = new circle(10); circle n = new circle(20); double bc = m.zhouchang(); double mj = (n.mianji()-m.mianji()); Console.WriteLine("內圓的周長為:"+bc); Console.WriteLine("花磚的面積為:"+mj); } }
首先做了一個名為circle的類,它可以生產任何一個半徑不同的圓,在建構函式中,為半徑賦值。
二:物件導向的三大特性
三大特性是指:封裝,繼承,多態。
類中的方法一般分為:構造方法(函數);屬性方法(函數):成員變數賦值取值;行為方法(函數):變數運算。
(一): 封裝
1.封裝含義:
(1)不同類的變數只屬於各自的類。
(2)不同對象的成員變數只屬於各自的對象,彼此不受影響。
(3)對象中的變數需要通過方法(函數)實現操作,比較安全。
封裝為了安全,盡量不用public來聲明變數,避免在main函數中可以直接存取賦值而降低了安全性,在類中建立public的方法來賦值,main中調用此方法傳值。
2. 成員變數及訪問修飾
private 私人成員 ,protected 受保護的成員,public 公有成員
3. 建構函式
它是一個特殊的成員函數,一般在建構函式裡進行初始化。如果不寫建構函式在new的時候會自動產生一個預設空的建構函式。
寫法特殊:沒有傳回值,函數名只能與類名一樣;public 類名(){};
執行特殊:類在執行個體化(new出來的時候)自動執行,建構函式是最早執行的成員函數,建構函式是用來產生對象的函數。
它的主要作用:對象執行個體化產生的時候,做一些初始化的工作。
下面例子就是做了一個Ren()的建構函式,為其變數賦上初始化的值:
class Ren { string _Name; int _Age; public Ren() { _Name = "龍神"; _Age = 25; } }
4. 重載(函數或方法)
函數名相同,參數不同(參數個數或類型不同)的多個函數就形成了重載。
重載只與函數名和形參有關,與傳回型別無關。
下面舉個例子,建構函式的重載:
class Ren() { string _Name; int _Age; public Ren() { _Name = "ZSMJ"; _Age = 25; } public Ren(string name) { _Name = name; } public Ren(string name,int age) { _Name = name; _Age = age; } }
這樣Ren類中就做了三個建構函式,第一個是無參的,第二個是一個string類型的參數,第三個是兩個參數,類型分別為string和int。他們符合重載的條件,所以會形成重載在Main函數中new的時候根據參數的不同會自動選擇執行其中一個建構函式。
如果在Main函數中:
Ren a = new Ren("王大鎚");
則執行的建構函式是第二個。
5. 屬性
它的聲明:public 類型 屬性名稱;也可以選擇成員變數右鍵重構,封裝欄位來產生屬性方法,例如:
string _Name; public string Name { get { return _Name; } set { _Name = value; } }
這樣Name就是該類的一個屬性,在Main函數中可以用此屬性為其成員變數賦值取值:
Ren a = new Ren("王大鎚"); a.Name = "王尼瑪";
注意:(1)屬性是用來為成員變數賦值和取值的,它有代替屬性方法的作用,一般用屬性。
(2)屬性定義的時候,屬性名稱後面沒有小括弧。
(3)屬性都是public。
(4)屬性中只能包含兩個部分:get和set。代碼也只能寫在get和set的花括弧裡面。
(5)屬性分為唯讀屬性,唯寫屬性和可讀寫屬性,與get和set的有無有關係。
6. this關鍵字
概念:this引用,this在哪個對象裡面執行代表該對象本身。
用法:this.成員變數(成員方法),this._Name; this.Eat();
例子:this 調用當前對象的其它建構函式。
public class Mydate { int _Year; int _Month; int _Day; int _Hours; public Mydate(int year,int month) { _Year = year; _Month = month; } public Mydate(int year,int month,int day,int hours): this(year,month) { _Day = day; _Hours = hours; } }
這裡第一個建構函式中有兩個參數year和month,在做第二個建構函式的時候為了方便用“:this”來調用了本類中第一個建構函式,這樣第二個建構函式只需寫後day和hours的執行語句就可以了。
在new的時候傳入不同的參數,會執行個體出不同的對象,這時候的this就代表不同的對象。
7. is關鍵字(運算子)
用法:對象 is 類名;is左邊是對象,右邊是類型;
Console.WriteLine(a is Ren);
如果a是一個Ren類的對象,則傳回值為true,否則傳回值為false。
8. partial關鍵字
如果一個類特別大,不宜擋在一個檔案中實現或者一個類中有一部分代碼不宜與其他混淆或者需要多人合作編寫一個類,這就需要將一個類拆開來寫。
用partial關鍵字可以實現,也可以用來補充完善類,擴充性比較強。 如在程式集裡的一個檔案裡寫了 partial class Ren{裡面是成員} ; 在另一個檔案裡也可以對Ren類進行補充,需要這樣寫 partial class Ren{裡面是成員} 。 9. 靜態成員
非靜態變數稱為執行個體變數,非靜態方法稱為執行個體方法,執行個體成員的資料存在每個對象中,用對象名來調用。
靜態成員包括:靜態變數,靜態屬性,靜態方法。
定義一個成員為靜態:在變數或方法前加static,如:static int a;
靜態變數是屬於類的,每個對象都有的並且相同的東西只儲存一份,不和執行個體變數那樣在每個對象裡都面儲存一份。
可以說它不屬於任何對象,也可以說它又屬於任何一個對象,給每個對象用,節省空間的。
例如:每包粉筆的顏色是靜態成員,每支粉筆的剩餘長度是執行個體成員。
靜態變數或方法不需要new出來。
在C#中,定義了一個粉筆的類:
class Fenbi { static string _Color; public static string Color { get { return Fenbi._Color; } set { Fenbi._Color = value; } } int _Lenght; public int Lenght { get { return _Lenght; } set { _Lenght = value; } } }
(1)在當前類的花括弧外,靜態成員只能用類名來調用,不能用對象名來調用,而執行個體成員只能用對象名來調用,不能用類名來調用。
Fenbi.Color ="Yellow"; Fenbi b = new Fenbi(); b.Lenght = 10;
(2)在當前類的花括弧內,靜態方法只能直接調用靜態成員,不能調用非靜態成員,執行個體方法可以調用非靜態和靜態成員。
public static void xiezi() { Console.WriteLine("寫出"+_Color+"的文字了"); }
public void change() { Console.WriteLine(_Color+"的粉筆長度變為:"+_Lenght); }
10. 拷貝
淺拷貝:傳遞引用,不賦值對象。
深拷貝:建立一個新的對象。
(二): 繼承
1. 文法:public 子類名:父類名;如:class Dog:Pet。
2. 特點:單繼承,一個父類可以派生多個子類,但每個子類只能有一個父類
如果一個類,沒有明確指定父類是誰,預設是object。除了object類之外,所有類都有一個父類。
子類可以從父類繼承下父類的成員變數和成員方法。
3. 存取修飾詞合存取權限:
private 的成員不被繼承,只能在該類中訪問。
protected成員可以被繼承,能在該類和衍生類別中訪問到,在外界訪問不到。父類中的變數一般用protected。
public成員可以被繼承,能在所有地方訪問到。
4. base 關鍵字:子類中可以用(base.父類中的成員 )來調用父類中的成員,base()調用父類構造,base.xxx()調用父類成員方法。
調用的參數值會被覆蓋,方法也會被覆蓋。
5. 繼承關係中執行個體化子類的流程:
先執行父類的建構函式,再執行子類的建構函式。
6. 繼承關係的執行個體化:
如果父類的建構函式沒有空參建構函式,全是帶參數的,則子類必須要寫建構函式,建構函式的形參中必須包含父類建構函式所需要的參數,還要用base()把父類建構函式所需要的參數傳遞父類。
例如:父類中只有這個建構函式
public Ren(string name, int age) { _Name = name; _Age = age; }
那麼子類中的建構函式應該這樣寫:
public Chinese(string name, int age, string yuyan):base(name,age) { _Yuyan = yuyan; }
7. sealed 關鍵字:
如果用來修飾class,稱為密封類,此類無法被繼承;如果用來修飾方法,該方法無法被重寫。
如: sealed class Ren{};
(三): 多態
1. 概念:父類引用指向不同子類執行個體的時候,父類引用所調用的函數都是子類的函數,由於子類對象不同,父類引用調用的成員表現出來的不同狀態就是一種多態。
2. 實現的方式:多態需要通過繼承來實現
3. 分類:分為編譯多態(重載overload)和運行多態(重寫override)。父類方法被重寫了之後也可以在子類中用base.方法 調用。
4. virtual關鍵字:虛方法,允不允許重寫,要重寫父類方法必須是虛方法:public virtual void Eat()。
5. 運行多態實現的條件:
(1)子類對父類方法的重寫(override),父類和子類中都有相同的方法。
(2)父類引用指向子類執行個體。
例如,有一個Ren類是父類,一個Chinese類和American是子類,Ren r = new Chinese();父類的引用 r 指向子類執行個體。
class Ren { protected string _Name; protected string _Country; public virtual void Eat() { Console.WriteLine("正在吃飯..."); } } class American : Ren { public override void Eat() { Console.WriteLine("正在用叉子和刀子吃飯...."); } } class Chinese : Ren { public override void Eat() { Console.WriteLine("正在用筷子吃飯..."); } }
父類Ren中有個Eat方法為虛方法,在子類Chinese和American中進行了重寫,在Main函數中:
Random rand = new Random(); int n = rand.Next(100); Ren a; if (n % 2 == 0) { a = new American(); } else { a = new Chinese(); } a.Eat();
隨機讓父類引用 a 指向 不同的子類執行個體,這樣用父類引用 a 調用方法Eat()的時候表現出不同對象的操作。
6. 裡氏代換原則和抽象依賴原則
裡氏代換原則,如果某個方法接收的是父類引用,可以向裡面傳父類或其子類的元素,子類對象替代父類對象。
抽象依賴原則,用父類的引用來指向子類的執行個體。
例子:怪獸吃人,傳入Ren的引用 r ,則r.Cry()表現出來不同的結果。
class Monster { public void EatFood(Ren r) //r = a; { r.Cry(); Console.WriteLine("人類真好吃,吃飽了!"); } } class Ren { public virtual void Cry() { Console.WriteLine("......."); } } class American:Ren { public override void Cry() { Console.WriteLine("MyGod,God bless me!"); } } class Chinese:Ren { public override void Cry() { Console.WriteLine("天哪,老天爺保佑我!"); } }
在Main函數中 ,先執行個體出一個怪獸,隨機產生一個Ren的對象,將此對象的引用傳入怪獸類裡,通過這個引用來表現出不同的狀態。
Monster m = new Monster();
Random rand = new Random(); int n = rand.Next(100); if (n % 2 == 0) { American a = new American(); //或者是這樣寫 Ren a = new American(); m.EatFood(a); } else { Chinese c = new Chinese(); //或者是這樣寫 Ren c = new Chinese(); m.EatFood(c); }
一:抽象方法
1. 在物件導向程式設計語言中抽象方法指一些只有方法聲明,而沒有具體方法體的方法。抽象方法一般存在於抽象類別或介面中。
在一些父類中,某些行為不是非常明確,因此無法用代碼來具體實現,但是類還必須具備此方法,因此,把這樣的方法定義為抽象方法。
2. 聲明方法:public abstract Eat(); 方法聲明只是以一個分號結束,並且在簽名後沒有大括弧,沒有函數體,因為太抽象不清楚,具體的實現由各個子類中重寫函數實現。
3. 它的特點:
(1) 抽象方法是隱式的 virtual 方法。
(2) 只允許在抽象類別中使用抽象方法聲明。
(3) 因為抽象方法只聲明不提供實實現,所以沒有方法體。抽象方法只在衍生類別中真正實現,這表明抽象方法只存放函數原型(方法的傳回型別,使用的名稱及參數),而不涉及主體代碼。
(4) 加abstract關鍵詞。
(5)抽象方法的目的在於指定衍生類別必須實現與這一方法關聯的行為。
二:抽象類別
1. 抽象類別:無法被執行個體化的類。關鍵詞是abstract,凡是帶有abstract關鍵詞的類都無法被new出來。抽象類別是不完整的,它只能用作基類。在物件導向方法中,抽象類別主要用來進行類型隱藏和充當全域變數的角色。
2. 聲明:抽象類別聲明:public abstract class Ren{};
3. 注意:
(1)凡是帶有抽象方法的類肯定是抽象類別;抽象類別卻不一定包含抽象方法。
(2)構造方法,靜態成員方法不能聲明為抽象方法。
(3)一個非抽象類別必須實現從父類繼承來的所有抽象方法,如果有一個抽象方法沒有實現,則此類必須要加abstract關鍵字。如果父類被聲明為抽象類別,並存在未實現的抽象方法,那麼子類就必須實現父類中所有的abstract成員,除非該類也是抽象的。
4. 特徵:
(1)抽象類別不能執行個體化。
(2)一個抽象類別可以同時包含抽象方法和非抽象方法。
(3)不能用sealed修飾符修飾抽象類別,因為這兩個修飾符的含義是相反的,採用sealed修飾符的類無法繼承,而abstract修飾符要求對類進行繼承。
(4)從抽象類別派生的非抽象類別必須包括繼承的所有抽象方法和抽象訪問器的實際實現。
例子:Ren類中有一個抽象方法Eat(),在其衍生類別Chinese和American中必須重寫這個方法
abstract class Ren { protected string name; public abstract void Eat(); } class Chinese:Ren { public override void Eat() { Console.WriteLine("用筷子吃飯"); } } class American : Ren { public override void Eat() { Console.WriteLine("用刀叉吃飯"); } }
三:介面
1. 關鍵字:interface,用interface 關鍵詞來定義。
2. 概念:極度抽象的類,無成員變數,無執行個體屬性和執行個體方法,只有抽象方法或抽象屬性,生活中的例子:標準,規則。
3. 寫法:介面不用class,用interface,名字一般以I作為首字母;不用寫abstract,裡面所有都是,不用寫public,必須是public。
interface IUSB //介面 { void start(); void stop(); }
4. 特點:
(1)介面中的方法都是抽象的,因此無需加abstract修飾符。
(2)介面中的方法都是公用的,因此無需加public修飾符。
(3)介面就是一個規則標準。
(4)介面可以繼承父介面。
(5)一個類可以實現(繼承)多個介面。一個類只能有一個父類,但可以實現多個介面。
例子:簡單的IUSB介面,裡面有兩個抽象方法start()和stop(),衍生類別實現介面必須實現介面中的所有方法。
interface IUSB //介面 { void start(); void stop(); } class UDisk : IUSB //實現介面必須實現裡面的所有方法 { public void start() { Console.WriteLine("隨身碟啟動了"); } public void stop() { Console.WriteLine("隨身碟停止了"); } } class Cammer : IUSB { public void start() { Console.WriteLine("網路攝影機啟動了"); } public void stop() { Console.WriteLine("網路攝影機關閉了"); } } class computer { public void CheckUSB(IUSB usb) { usb.start(); } public void CloseUSB(IUSB usb) { usb.stop(); } }
用的時候:
computer c = new computer(); UDisk u = new UDisk(); Cammer m = new Cammer(); c.CheckUSB(u); //插入隨身碟 c.CheckUSB(m); //插入網路攝影機 c.CloseUSB(u); //拔出隨身碟 c.CloseUSB(m); //插入網路攝影機
四:命名空間
1. 概念:namespace 相當於一個包,它是對類進行分類管理的工具,給電腦看的,相同命名空間下的類可以分在不同的檔案中儲存。
2. 一般寫法:namespace 公司名.項目名.模組名
3. 在別的命名空間上面要使用其它命名空間內的類,可以在它的上面寫 using 要使用的命名空間;
五:項目名
一般預設:ConsoleApplication1,用來給人類標識出這個項目是做什麼的,給人看的。
六:程式集
在項目名上打右鍵:屬性,即可修改程式集名稱
編譯出來的exe或dll檔案就是程式集。exe是控制台應用程式,dll是庫類。
程式集的名字就是編譯出來的exe或dll名字。
如果一個項目分三個人來寫,A寫一個類庫,B寫一個類庫,C寫Main函數,把他們整合在一起的流程是:
1. A寫完了編譯出一個名字如 cc.dll 的檔案;
2. B寫的時候要用到A命名空間中的某個類,B先將A的cc.dll檔案拷貝到自己的目錄下,B需要在項目中的引用上打右鍵:添加引用,通過瀏覽找到該引用添加進來,然後using A 的命名空間;
3. B寫完了編譯出一個名字如 dd.dll 的檔案;
4. C要寫Main函數,在Main函數中操作AB中的類,他需要將AB的dll檔案拷貝過來,然後再項目中的引用上打右鍵,添加引用,通過瀏覽找到該引用添加進來,然後using A 的命名空間; using B的命名空間,這樣就可以在Main函數中用了。
5. 如果A的命名空間中有個類Ren和B的命名空間中有個類Ren重名了,這C在用的時候要用哪一個命名空間下的Ren類就要用該命名空間點出來再用。
C#物件導向