繼承是C#的三大特性之一,它實現了多態性和代碼復用
我們可能會在一些類中,寫一些重復的成員,我們可以將這些重復的成員,單獨的封裝到一個類中,作為這些類的父類。
Student、Teacher、Driver 子類 派生類
Person 父類 基類
1. 子類繼承了父類,那么子類從父類那里繼承過來了什么?
首先,子類繼承了父類的屬性和方法,但是子類并沒有繼承父類的私有字段。
子類對象可以調用父類中的成員,但是父類對象永遠都只能調用自己的成員。
2. 問題:子類有沒有繼承父類的構造函數?
答:子類并沒有繼承父類的構造函數,但是。子類會默認的調用父類無參數的構造函數,創建父類對象,讓子類可以使用父類中的成員。所以,如果在父類中重新寫了一個有參數的構造函數之后,那個無參數的就被干掉了,子類就調用不到了,所以子類會報錯。
解決辦法:
1)、在父類中重新寫一個無參數的構造函數。
2)、在子類中顯示的調用父類的構造函數,使用關鍵字:base()
3. 在創建子類對象的時候,為什么會先在子類對象的內部創建一個父類對象出來?
由于繼承的原因,子類能夠使用父類的屬性和方法,如果沒有創建父類的對象的話,就不能夠使用父類的屬性和方法了。
4. 繼承的特性
1、繼承的單根性:一個子類只能有一個父類,不允許多重繼承。
2、繼承的傳遞性: 祖宗的東西遲早都是我的,子類的派生類也可以調用子類的父類的方法。
A 繼承 B,C是A的派生類,那么C也可以調用B的屬性和方法。
5. object類是所有類的基類
6. new關鍵字的作用
1)、創建對象 Class1 c = new Class1();
2)、隱藏從父類那里繼承過來的同名成員。
隱藏的后果就是子類調用不到父類的成員。
子類與父類 盡量不要出現同名的成員,如果有請使用new來隱藏
public class Animal { public virtual void Eat() { Console.WriteLine("Animal eat"); } } public class Cat: Animal { public new void Eat() { Console.WriteLine("Cat eat"); } public void Eating() { Console.WriteLine("Cat eating"); } } class Program { static void Main(string[] args) { Animal a = new Animal(); a.Eat(); Animal ac = new Cat(); ac.Eat(); //輸出:Animal eat 并非Cat eat //ac 這個對象無法調用 Cat類的eating方法 Cat c = new Cat(); c.Eat(); } }
輸出結果:
Animal eat
Animal eat
Cat eat
第2句為什么會是 Animal eat 而非Cat eat呢?
因為,使用new關鍵字后,使得Cat中的Eat()方法和Animal中的Eat()方法成為毫不相關的兩個方法,只是它們的名字碰巧相同而已。
此時,對于ac這個對象而言,Cat中的Eat()方法就如同Eating()方法了,它們都是Cat類獨有的方法,ac無法調用到它們。
假如我們只使用了new關鍵字,如果Cat類沒用從Animal類繼承Eat()方法,編譯器會輸出警告!
在程序中,Animal類型的對象ac指向了Cat類型的對象所占據的內存時,Cat中的Eat()方法和Animal中的Eat()方法毫無關系,所以Cat中的Eat()方法就是Cat類中獨有的方法了。這樣ac無法調用Cat中的Eat方法,于是就會去調用Animal中的Eat方法。
7. 里氏轉換原則
1)、子類可以賦值給父類
2)、如果父類中裝的是子類對象,那么可以講這個父類強轉為子類對象。
Hero[] heros = new Hero[10]; Random ran = new Random(); // 里氏轉換的第一條規則: 子類可以賦值給父類 for (int i = 0; i < heros.Length; i++) { int random = ran.Next(1,6); switch (random) { case 1 : heros[i] = new ZhuGeLiang(); break; case 2: heros[i] = new SunShangXiang(); break; case 3: heros[i] = new SiMaYi(); break; case 4: heros[i] = new CaiWenJi(); break; case 5: heros[i] = new Hero(); break; } } //里氏轉換的第2條規則:如果父類中裝的是子類的對象,那么就可以將這個父類強轉為子類的對象。 for (int i = 0; i < heros.Length; i++) { //heros[i].LaunchSkill(); if (heros[i] is ZhuGeLiang) { ((ZhuGeLiang)heros[i]).WatchStar(); } else if (heros[i] is SunShangXiang) { ((SunShangXiang)heros[i]).GetMarried(); } else if (heros[i] is SiMaYi) { ((SiMaYi)heros[i]).GostSkill(); } else if (heros[i] is CaiWenJi) { ((CaiWenJi)heros[i]).SorrowSong(); } else { heros[i].LaunchSkill(); } } Console.ReadKey(); } class Hero { public void LaunchSkill() { Console.WriteLine("我是白板,沒有技能。"); } } class ZhuGeLiang : Hero { public void WatchStar() { Console.WriteLine("知天易逆天難。"); } } class SunShangXiang : Hero { public void GetMarried() { Console.WriteLine("他好,我也好。"); } } class SiMaYi : Hero { public void GostSkill() { Console.WriteLine("吾乃天命之子。"); } } class CaiWenJi : Hero { public void SorrowSong() { Console.WriteLine("悲歌可當泣,遠望可當歸。"); } }
文章列表