C#面向對象

C#面向對象(一)

 

一:面向對象的基本知識html

C#程序分爲面向過程和麪向對象編程

什麼是對象:一切皆爲對象:Object,生活中常說的「東西」就是程序裏面所指的對象;生活中遇到的東西咱們都在下意識的歸類;歸類意味着抽象模型;安全

類:class,對某類衆多對象的共同特色抽象出來的模型。less

他們的關係:類是好多對象的抽象,對象是類的實例化。dom

建立一個名爲Dog的類:編程語言

複製代碼
複製代碼
 class Dog  //通常首字母大寫
    {
       int age;
       public void setage(int a) //用方法賦值
        {
           age = a;
        }
       public void buck()
        {
            Console.WriteLine("這是一個方法");
        }
    }
複製代碼
複製代碼

類中通常包括兩類東西,變量(名詞,也交成員變量這裏age是成員變量)和函數(動詞,也叫成員函數或成員方法 buck()就是方法)。ide

對象實例化:函數

Dog d1 = new Dog();

這樣就實例化出了一個Dog的對象a。工具

例子:兩個套在一塊兒的圓,求內圓的周長和內圓與外圓之間的面積,用面向對象的思想作post

複製代碼
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("U盤啓動了");
        }
        public void stop()
        {
            Console.WriteLine("U盤中止了");
        }
    }
    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); //插入U盤
       c.CheckUSB(m); //插入攝像頭

       c.CloseUSB(u); //拔出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類就要用該命名空間點出來再用。

相關文章
相關標籤/搜索