C#面向對象基礎


1、  為什么要有面向對象?

(1)       增加代碼重用。

(2)降低維護負擔,將具備獨特性質的代碼封裝起來,修改程序時,相互不會影響。

2、數據封裝用來解決全局變量不易維護的問題。

3、多態:為了加強繼承的彈性,常常需要子類對父類的方法進行重寫(函數名稱不變)。

4、抽象化是為了降低程序版本更新后的維護負擔。使功能的提供者和使用者分開,各自獨立,彼此不受影響。

5、為了抽達到象化,提供接口用於建立功能提供者和使用者之間的規范。功能提供者和使用者按照這個規范來提供、使用這些功能。這個功用的規范就是接口。接口中定義了常量、函數名稱、函數參數等。因此接口不改變的情況下,功能提供者就可以任意的改寫函數中的代碼,而不會影響到使用者使用這些功能。

 

       抽象化的優點:

       .可編寫函數處理有相同接口的類

例如:員工薪水的發放:按照職位、工齡發放,只需要定義一個計算薪水的接口,然后分別實現。

.用於未來功能的擴展。

.讓功能提供者和使用者相互獨立。

6、通常繼承應用在公司的內部開發上,以重復使用其他設計師編寫好的代碼;而接口多半是用於兩個部門或兩家以上的公司,用於分別開發自己的應用程序時建立的公用的規范。

7、類是數據封裝的基本單位。是重復使用的最小單位。

       類的成員:變量、方法、屬性、事件、常數

       對象是類在內存中的實體,類用於描述對象在內存中的數據。也就是說類用於定義對象的長相。

8、靜態方法可以不建立類的對象,即不用new實例化,而用類直接調用:類名.方法名()

       Static變量通常用於配置全局共用的區塊

9、new實例化對象后,對象將會被配置在堆積Heap中,堆棧Stack內保存的是指向堆積Heap中對象所在位置的參考指針。實例化的那個對象用於存放的是指針。實例化的對象是放在堆棧中的,如下圖:

9、結構和類的區別:結構主要由簡單的數值類型組合而成,配置在堆棧中。類屬於參考類型,配置在堆積中。結構不支持繼承。

10、數據封裝:使用類進行封裝。

       封裝目的:數據和方法被封裝起來,通過方法存取數據。可以控制數據的存取方式。

11、訪問修飾符:

       public:所有

       private:類中的方法和成員只能在此類中使用,外部不能使用。

       protected:類自身可以使用、子類也可以使用。protected並不是被派生類隨心所欲的訪問,訪問是有條件的:訪問必須是子類類型發生時,父類的protecte成員才能夠被訪問

       internal:同一個.NET Assembly中可以使用

       protected internal:只限定在目前的項目或繼承自此類的成員才可以使用

注意:在聲明方法是,默認識private

       一個好的面向對象的設計,通常把所有的數據成員定義為private,然后提供方法來存取這些數據

12、數據封裝的目的:易於控制數據、容易修改。

13、靜態成員:

       對象中的數據都是對象私有的,只有對象才能操作這些數據,其他對象不能操作。那么有時候把所有對象共用的數據保存在每一個對象中並不是很好,比如一個公司的所有員工同屬於這個公司,若在員工類中定義一個存放公司名稱的成員變量,那么,在實例化對象后,都需要用:對象名.方法名() 來存取公司名稱信息,這樣若公司名稱改變了,維護起來比較麻煩,並且計算機還要分配內存、硬盤空間等,為了解決這個問題,在實現的時候會將這種數據放在全局的內存區塊上,也就是說,這個數據不是對象能夠操作的,而是類級別的,對象操作不了。但是,全局的數據並不是保存在類中的,因此,不能夠使用封裝的技巧使用全局變量,取而代之的是以靜態static的方式來描述這樣的數據。靜態類就是用來描述類中共用信息的。

       靜態數據是在類中聲明的,所以能夠體現封裝的特性。就算這個定義了靜態數據的類沒有被實例化,該靜態數據還是存在的。所以,不用建立對象實體就可以對靜態數據進行操作。

       編譯器會在類載入是自動初始化static變量,也就是說,若靜態的成員變量沒有被賦值,那么在編譯時,編譯器會自動給變量賦值。String類型是空字符串,int類型是0,bool類型是false,生命周期被限定在應用程序的生命周期中

14、靜態方法:

       對靜態數據進行操作需要使用靜態方法,靜態方法屬於類,是類級別的,不是對象能夠操作的,靜態方法不能用this保留字

       通常,編譯器Compiler在編譯時會將靜態數據和靜態方法當做全局變量或全局函數來對待。默認的靜態數據是private的

       靜態方法不能夠存取非靜態數據和非靜態方法。

       windows應用程序中Main()方法定義為public static,不需要實例化Runtime就可以直接運行Main().靜態方法只能用類調用,非靜態方法用實例調用。

15、this操作數

       this操作數是指向此對象的參考指針。也就是實例化后就可以使用this來存取這一對象實體。還可以用於解決名稱相同的問題:this.Name=Name(參數)。this還可以用來返回目前對象的參考: this.Name=Name ;return this。

16、類默認的訪問修飾符是private

17、internal修飾符是類型和類型成員的訪問修飾符。只有在同一個程序集的文件中,內部類型或者是成員才可以訪問,Assembly:一個完整的.exe或者是.dll文件就是一個程序集。

18、參考類型:

實值類型:包含的是真正的數據,不能為null。堆棧。

參考類型:一個指向實際數據的參考指針。堆積。

 

封裝、繼承、多態

繼承:

1、C#語言提供兩種繼承的方式:實現繼承(只能單一繼承)和接口繼承(可以多繼承)

UML中

類名

Employee

成員變量

-CompanyName:string

-EmployeeID:int

-EmployeeName:string

-EmployeeSalary:string

方法

+SetID(in ID:String):void

+GetID():string

+SetCompanyName(in   CompantName:String):void

 

 

 

成員變量:-CompanyName:string字符串類型,“-”表示private訪問修飾符,成員變量下方                       加底線表示static

方法:+SetID(in ID:String):void  in 表示輸入參數 void表示不返回值,有下划線表示static

子類不能繼承父類的構造函數和析構函數。

繼承默認是public

2、Base:代表基類中調用父類的構造函數,注意,這個構造函數的的參數個數和類型必須和基類中某一個構造函數一樣。Base的另外用法是調用基類的成員(成員方法),如:

父類:

namespace ClassTest

{

    public class Employ

    {

        public Employ(string EmployeeNum)

        {

             }

        private string employeeNum;//員工編號

            public void SetEmployeeID(string EmployeeNum) //設置員工編號

        {

            employeeNum = EmployeeNum;

        }

     }

}

子類:

namespace ClassTest

{

    public class U_base:Employ

    {

        public U_base(string EmployeeNum)

            : base(EmployeeNum)  //base指基類中的構造函數,參數類型和個數必須相同

        {

            base.SetEmployeeID(EmployeeNum);  //這里的base是用於調用基類中的成員方法

        }

    }

}

3、基類重寫override父類方法,這是多態的一種表現形式,是對基類中的方法進行重新定義。方法名以及參數和基類中的相同,只是方法內部代碼不同。(重載是同一個類中的同一種方法的返回值可以相同,也可以不同,是一個類中多態的一種表現,參數不同)

4、虛擬方法

體現多態。一個類中默認的方法都是非虛擬的,不允許在同一個類中用相同的方法去實現不同的功能

虛擬方法不可以是靜態的。因為靜態方法是類級別的,而多態只能體現在對象級別。

Virtual不能用private修飾,否則沒法再子類中重寫。

Virtual方法可以有具體的實現,而abstract方法不能有具體的實現,abstract方法必須在子類中用override來實現。

基類中的Virtual方法被子類中的override重寫是,方法的修飾符(不存在修飾符權限大小問題,必須相同)、名稱、參數、返回值必須相同。

Virtual和override不能同時使用,因為override方法是隱含virtual的。

override不能和private、static一起使用,因為靜態方法是類級別的,而多態只能體現在對象級別;override方法必須要改寫virtual方法,若設置為private就不能改了。

virtual用來修改基類的方法或屬性的定義部分。虛擬成員或虛擬函數可以在子類中改寫其功能。Virtual用於基類中。Virtual方法可以被實例化成員調用。

具體用法是在基類中定義virtual方法,然后根據需要在子類中重寫override功能,沒有用virtual聲明的方法不能用override重寫,否則出錯。

若基類和子類中有相同的方法,那么基類的方法被子類覆蓋,基類能夠調用自己的該方法,子類調用的該方法是子類自己的該方法。

注意:不管是基類中的virtual還是子類中的override方法,都能被各自的類調用。

5、final最終類不允許繼承,里面的方法不允許override

6、new關鍵字

在子類中定義方法用以取代基類中的方法,但是基類中的該方法還是能夠被基類的實例調用,而不能被子類實例使用了。子類中用new修飾的方法只能用子類的實例調用。使用new和在子類中直接定義一個和基類中的方法相同的方法的效果是一樣的,不過這樣會有警告。

7、sealed類(例如enum、String)和sealed方法

Sealed類防止類被繼承,也就是說sealed類不能作為基類。Sealed方法不能被override重寫

8、C#中允許將基類的類型指針指向子類:B:A{…} A a=new A();B b=new B();A c=b;這里的c是A的實例,若c.方法名(),則調用的是A中的方法。當然,若A中有virtual方法,那么A c=b就會先調用A,然后發現A中的方法用virtual修飾,會進一步檢測B中的方法,若B類中的方法被virtual修飾,則A、B中的方法不相關,若B中的方法用new修飾,表明這是一個新的方法,,最終調用的是還是A中的方法。若B中的方法用override修飾,表明這是一個新的方法,,最終調用的是還是B中的方法。

9、接口

為了達到抽象化,需要在功能的定義和使用之間提供一種公共的規范,以便提供者和用戶都能夠按照規范進行操作。這樣的規范就是接口。接口只是定義了規范,沒有具體的實現(抽象類可以有具體的實現),接口支持多繼承,類支持單繼承。接口中定義的方法不能包含區塊內容,也就是說不應該有大括號:public interface Job{double C(){}};這是錯誤的,定義在接口中的方法隱含都是public,若定義的時候再加上public就會報錯啊。類一旦繼承了接口,就應該實現接口中的所有方法,而且實現時要和接口中該方法完全相同(修飾符、返回值、方法名稱、參數),繼承自接口的方法可以用virtual關鍵字修飾,用於自他類繼承。但是接口中的方法不能用virtual,也不能有修飾符。

10、抽象類、抽象方法

抽象類和接口一樣不能實例化。抽象方法隱含是virtual的,所以不能和virtual連用。抽象方法只能定義在抽象類中。抽象方法只能由定義部分,不能有大括號,抽象方法一定要在子類中實現。和接口類似,抽象方法和virtual修飾的方法的區別是virtual可以有實現部分,即大括號。抽象類可以繼承自非抽象類、抽象類。

抽象類和接口都不能使用sealed修飾,接口中不能包含抽象方法,抽象方法中可以使用ovreride、new修飾符


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM