面向對象開發有三大特性(特色 / 特徵) : 封裝, 繼承, 多態。咱們今天主要討論封裝和繼承,多態會在下篇中討論。編程
所謂封裝,也就是把客觀事物封裝成抽象的類,而且類能夠把本身的數據和方法只讓可信的類或者對象操做,對不可信的進行信息隱藏。封裝是面向對象的特徵之一,是對象和類概念的主要特性。簡單的說,一個類就是一個封裝了數據以及操做這些數據的代碼的邏輯實體。在一個對象內部,某些代碼或某些數據能夠是私有的,不能被外界訪問。經過這種方式,對象對內部數據提供了不一樣級別的保護,以防止程序中無關的部分意外的改變或錯誤的使用了對象的私有部分。ide
A.public [公開訪問]函數
公開的訪問權限。優化
當前類, 子類, 實例對象, 均可以訪問到。this
B.private [私有訪問]spa
私有的訪問權限。設計
只能在當前類內部進行訪問使用; 子類, 實例對象, 都訪問不到。code
C.protected [保護訪問]對象
受保護的訪問權限。blog
只能在當前類的內部,以及該類的子類中訪問;實例對象訪問不到。
也就是說受保護的,不讓外部的實例去訪問和改變。
D.internal [內部訪問]
只能在當前程序集(項目)中訪問;
(程序集能夠理解爲一個項目,一個項目也就是一個程序集。從設計的角度來講,也能夠當作是一個完整的模塊(Module),或者稱爲是包(Package)。所以,一個程序集也能夠體現爲一個dll文件,或者exe文件。一個解決方案下能夠用不少項目,項目名和命名空間名能夠分別設置,但默認狀況下是一致的,而對應到項目的具體文件夾就是「項目的命名空間.文件夾名
在同一個項目中 internal 和 public 的訪問權限是同樣的。
一個解決方案裏面,能夠有多個項目!
E.protected internal [內部保護訪問]
protected + internal 的訪問權限。
用的很少,我是沒用過的。
A.修飾類
可以修飾類的訪問修飾符只有兩個, public 和 internal;
類的默認訪問修飾符是 internal。默認類就是那種前面沒有修飾符的class
B.修飾類成員
五種訪問修飾符均可以修飾類中的成員;
類中的成員默認訪問修飾符是 private。
C.類視圖
當前項目上右鍵-->視圖-->查看類圖
能夠看到類的繼承關係圖, 以及類中的成員概況。
各位留意一下字段,屬性,方法各自特有的圖標。
字段是小磚塊,還上鎖了。屬性是小扳手。方法是空的小盒子。
下面是類視圖。
將一堆類中的一些共有的「成員」單獨抽取出來,做爲一個父類,而後這一堆類繼承這個父類,共享父類的資源, 這就叫作繼承。
覺得人爲例,咱們每一個人都會有一些共同的特徵,都要作一些相同的事情。好比:人都有一個腦殼,二隻胳膊,二條腳,這是共同的特徵。都要吃飯,喝水,這是都要作的相同的事情。那麼若是咱們如今要聲明不少我的,每一個人都會有這些特徵,那我不是要寫不少重複的代碼?因此咱們能夠先建一我的的父類,這個父類不表明一個具體的人,只是一個擁有人全部共同特性的虛擬的人。下次我 們要實例化一個具體的人的時候,只須要將這我的繼承上面這個「虛擬的人」,那麼他就擁有了人的全部共同特性。這樣,這些重複的代碼咱們就能夠不寫了。
固然,繼承的目標不只僅是爲了節省代碼,還有實現後面的多態的功能。初學者只須要了解繼承能夠少寫不少代碼就行了,餘下的須要在項目中慢慢理解。
書面的解釋以下:對象的繼承表明一種"is-a"的關係,假如兩個對象A和B,若是能夠描述爲"B就是A",那麼則表示B能夠繼承自A。
注意: 若是A繼承了B,那麼A不只擁有了B除私有的特性外的全部特性,A還能夠擁有本身獨特的特性。好比上面人的這個例子,一個繼承了 「虛擬的人」,那麼他除了有一個腦殼,二隻胳膊,二條腳,要吃飯喝水外,他可能還會編程。編程就是他獨特的特性了,由於不是每一個人都會編程的。
①優化代碼結構, 讓類與類之間產生關係(人不是孤立存在的, 類也同樣);
②提升代碼的複用性, 便於閱讀(寫更少的代碼, 幹更多的活);
③爲「 多態」 提供前提(多態是面向對象最複雜的一個特性, 後面重點講解)。
以電視劇舉例, 見圖。
(1)、延續:父類存在,子類沒有重寫但可使用;
(2)、新增:父類沒有,子類新增長的
(3)、重寫:父類子類都存在,可是父類不知足要求,子類對其進行重新定義;
(1)、先父類後子類,先靜態後成員;
實例化的時候先調用父類的靜態構造快,在調用父類的構造方法,而後子類的構造塊,在調用子類的構造方法;
(有繼承關係的幾個類中,構造函數是由上至下調用的,即首先調用基類的構造函數。父親會的,兒子也會,不先把父親弄出來,兒子何來會?
(2)、默認調用父類空構造;
(3)、那麼子類如何繼承父類的構造方法呢,要按以下寫法
編寫父類的構造方法
演示: 在 Hero 類中建立構造方法, 用於初始化父類中的成員。
public Hero(string m_heroName, string m_heroInfo, int m_attack, int m_defense, int m_speed, string m_nickName) { this.heroName = m_heroName; this.heroInfo = m_heroInfo; this.attack = m_attack; this.defense = m_defense; this.speed = m_speed; this.nickName = m_nickName; }
編寫子類的構造方法
演示: 在各個子類中編寫各自的構造方法, 使用 base 關鍵字傳值給父類。
關鍵字 base,表明父類;
關鍵字 this,表明當前類。
public LuKaShi() { } public LuKaShi(string m_heroName, string m_heroInfo, int m_attack, int m_defense, int m_speed, string m_nickName) : base(m_heroName, m_heroInfo, m_attack, m_defense, m_speed, m_nickName) { }
這裏他不作任何處理,直接扔給父類。
(4)、繼承之成員繼承:構造方法
構造方法可使用 private 和 public 進行修飾。但 99%的時候使用 public 修飾, 只有在使用單例模式的時候才使用 private 修飾。
private 修飾的構造方法, 咱們在子類中訪問不到;
public 修飾的構造方法, 咱們在子類中能夠訪問到, 使用 base()。
父類在內存是實際存在的。
2.6.1 重寫與重載:
重寫override:繼承的子類中,方法簽名相同( 方法名+形參個數 類型 順序 )
重載overload:同一個類方法名相同,形參個數 類型 順序 不一樣(只要有一項不一樣,便可構成重載)
2.6.2 重寫規則:在子類中籤名與父類中相同,在合理範圍內提升子類可見性;
這裏沒總結好,先學再總結下
A、父類必須有公共(public)或受保護(protected)的虛方法(virtual);
返回類型:基本類型和void必須相同;引用類型要<=父類的返回類
在派生類裏使用override關鍵字來重寫父類的虛方法。
B、抽象方法,接口,標記爲virtual的方法能夠被重寫(override),實方法不能夠。
C、可見性:要大於或等於父類中被重寫的方法(重寫方法的訪問修飾符必定要大於被重寫方法的訪問修飾符(public>protected>default>private))
D、重寫和覆蓋的區別