1. 程式人生 > >C#基礎(2)

C#基礎(2)

i++ body 相同 代碼筆記 發布 product 產品 直接 只需要

摘要:面向對象編程是很多編程語言的一種重要思想。萬物皆對象。有很多種不同個人理解,其實,用的多了,也就能夠去體會和領悟這種思想。個人理解:一個類或者接口, 就是對象,面向對象就是對類或者接口的操作,例如用到一個非靜態類,需要先new一個這個類的對象,繼承接口需要實現接口中的方法等。 此篇博客主要涉及到之前學習面向對象時的一些代碼筆記以及總結。

涉及內容: 1、裏氏替換原則 2、多態之虛方法 3、多態之抽象類 4、工廠設計模式 5、接口

----------------------------------------------------------------------------------------------------------------------------

面對對象(三大特征,五大原則):

三大特征:封裝、繼承、多態

五大原則:

單一原則: 一個對象應該只包含一個單一的職責,並且該職責被完整的封裝在一個類中。如果一個類中封裝了過多的職責,這些職責在並發執行的時候回相互幹擾

開放封閉原則: 對擴展開放,對修改代碼封閉(主要考慮安全性)

依賴倒轉原則: 高層(heigh leve1)模塊不該直接依賴低層(low leve1)模塊。它們兩個應該依賴抽象

裏氏替換原則: 子類能夠替換它們的父類

接口隔離原則: 客戶端不應該依賴那些它不需要的接口

-------------------------------------------------------------------------------------------------------------------------------

封裝:封裝類,封裝成方法 --解決代碼冗余

繼承:子類繼承父類

1、裏氏替換原則

a、子類可以賦值給父類

如果有一個方法需要一個父類作為參數,我們可以傳第一個子類對象 ,例如:需要一個object類型作為參數,可以傳遞任何類型的參數 (任何子類都繼承object)


b、如果父類中裝的是子類對象,則可以將這個父類強轉為子類對象

2、多態之虛方法

面向對象多態優點:①解決代碼冗余 ▲②:屏蔽各個子類之間的差異,寫出通用的代碼,適用於每個子類的調用

虛方法的使用:

//父類
public class Person
{
public string Name { get; set; }
public Person(string name) { this.Name = name;
}
public virtual void SayHello() { Console.WriteLine("我是人類"); } //子類① public class Chinese:Person { public Chinese(string name) : base(name) { } public override void SayHello() { Console.WriteLine("我是中國人,我叫{0}",this.Name); }
}
//子類② public class America:Person { public America(string name) : base(name) { } public override void SayHello() { Console.WriteLine("我是美國人,我叫{0}",this.Name); } } //調用實例: Chinese ch = new Chinese("張三"); America a1 = new America("喬布斯"); Person[] per = { ch,a1 }; for (int i = 0; i < per.Length; i++) { per[i].SayHello();
}
//結果: 兩個子類的SayHello方法

 以上實例:將父類的方法標記為虛方法,使用關鍵字virtual,這個方法可以被子類重新寫一遍。

 在父類的方法前面加上一個virtual,在子類的方法前面加上一個override;如果子類的方法前面不加override,編譯器不會報錯,但這樣的話,就無法通過父類來調用子類的方法,因為這個方法成了子類的獨有的方法,只是名字與父類相同而已,與父類無關。通過父類調用子類的方法,屏蔽子類之間的差異

3、多態之抽象類:(常用:工廠設計模式)

問題:運用多態求一個圓與矩形的面積 思考:圓的面積和矩形面積的求法不一樣,如何通過寫一個父類,然後調用父類的方法,屏蔽子類間的差異?父類根本無法構造方法體

//父類: 
  public abstract class Graph
 {
     public abstract double Getarea();       //抽象類沒有方法實體
  }

//子類①:圓
 public class Circle : Graph
 {
    public double R { get; set; }
    public Circle(double r)
    {  this.R = r;  }
    public override double Getarea()
    {
      return Math.PI * R * R;
    }
  }
//子類②:矩形
public class Rectangle : Graph
{
  public double Hight { get; set; }

  public double Width { get; set; }

  public Rectangle(double width, double hight)
  {
   this.Width = width;
   this.Hight = hight;
  }
  public override double Getarea()
  {
    return Width * Hight;
   }
}

//調用實例:
Graph gh = new Circle(3)
double circlearea= gh.Getarea();        //求圓的面積
Graph gh2 = new Rectangle(2, 4.2);
double rearea = gh2.Getarea();            //求矩形面積

 抽象類的特點:

 a、抽象類中的抽象成員必須標記為abstract,並且不能有任何實現。方法不能有任何實現是指,方法沒有大括號,也沒有方法體。 只有大括號,沒有方法體的方法叫做空實現。

 b、抽象成員必須標記在抽象類中

 c、抽象類是有構造函數的,但抽象類不能被實例化

 d、子類繼承抽象類後,必須把父類中的所有抽象成員都重寫。(除非子類也是一個抽象類,則可以不重寫)

 e、在抽象類中可以包含實例成員,並且它們可以不被子類實現

以上實例說明:不知道如何去寫父類這個方法,通過new子類實現抽象方法,屏蔽子類間的差異。上面簡單用下抽象類,常用於:工廠設計模式

4、工廠設計模式:

參與者:Product:抽象產品類,將具體產品類的公共代碼抽象和提取後封裝在一個抽象產品類中(抽象類的抽象方法)

Concerteproduct:具體產品類,將需要創建的各種不同產品對象的相關代碼封裝到具體產品類中 (繼承抽象類的子類的各自方法)

Factory:工廠類,提供一個工廠類創建各種產品,在工廠類中提供一個創建產品的方法,該方法可以根據傳入的參數不同創建不同的產品對象

Client: 客戶端類,只需要調用工廠類的工廠方法,傳入相應的方法即可獲得產品對象(實現)

5、接口:

特點:a、接口是一種規範 只要一個類繼承了一個接口,這個類必須實現接口的所有成員

b、接口不能被實例化 也就是說不能創建對象

c、接口與接口之間可以繼承 並且可以多繼承,接口不能繼承一個類

d、接口中的成員不能加訪問修飾符 默認為public

接口作用很大:首先實現了多繼承,另外常用:不同層之間通過調用接口提高安全性(例:業務邏輯層調用數據會話層的接口)。

實現 發布訂閱模式(觀察者模式):我們作為訂閱者不必每次都去查看這個公眾號有沒有新文章發布, 公眾號作為發布者會在合適時間通知我們(繼承接口)

我們與公眾號之間不再強耦合在一起。公眾號不關心誰訂閱了它,不管你是男是女還是寵物狗,它只需要定時向所有訂閱者發布消息即可(遍歷訂閱者)

總結:什麽時候用虛方法來實現多態?什麽時候用抽象類來實現多態?什麽時候用接口來實現多態?

在我提供給你的幾個類當中,如果說你能抽象出來一個父類,並且這個父類必須寫上這幾個子類共有的方法,然後你還不知道怎麽去寫這個方法,就用抽象類來寫這個多態
反之,抽象出來的父類,方法可以寫,並且我還要創建這個父類的對象,就用虛方法
這幾個類裏面根本就找不出來父類,但它們都有一個共同的行為,共同的能力。這個時候就用接口來實現多態

面向對象多態確實是一個很抽象的東西,具體運用可以根據需求,根據業務邏輯去選擇使用。

C#基礎(2)