文章出處

  繼承是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("悲歌可當泣,遠望可當歸。");
            }
        }

 


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()