程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C#之繼承

C#之繼承

編輯:C#基礎知識
本文意在鞏固基礎知識,並不是對其進行深入剖析,如若對各位高手沒有什麼作用,請繞過。
本文為原創文,所有示例均是博主測試過的,歡迎大家批評指正,如有轉載請標明出處,謝謝。
繼承、封裝和多態是面向對象編程的重要特性。
其成員被繼承的類叫基類也稱父類,繼承其成員的類叫派生類也稱子類。
派生類隱式獲得基類的除構造函數和析構函數以外的所有成員。 派生類只能有一個直接基類,所以C#並不支持多重繼承,但一個基類可以有多個直接派生類。
繼承是可以傳遞的
即: 如果 ClassB 派生出 ClassC,ClassA 派生出 ClassB,則 ClassC 會繼承 ClassB 和 ClassA 中聲明的成員。  class A
    {
        public void Sum(int i,int j)
        {
            int sum = i + j;
            Console.WriteLine("I am A ,my sum ={0}",sum);
        }
    }
    class B : A
    {
        public void Minus(int i,int j)
        {
            int minus = i - j;
            Console.WriteLine("I am B ,my minus ={0}", minus);
            this.Sum(3, 4);         }

    }
    class InheritanceTest1
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.Minus(3, 4);
            Console.Read();
        }
    }

結果:I am B ,my minus=-1

     I am A ,my sum = 7 試想一下,當基類Sum()方法是私有時,派生類還會繼承該方法嗎?
經過本人測試,沒有在B類找到該方法,那麼是不是它就沒有被繼承呢?其實不是的,私有成員其實已經被繼承了,
但是它們卻不可以被訪問,因為私有成員只能被聲明它們的類或結構體中才可訪問,所以看上去像是沒有被繼承。

如果我們想降低訪問基本,我們可以把基類Sum()方法定義為protected。
能夠阻止某個類被其他類繼承嗎?
答案是可以的,C#提供了一個sealed 修飾符,此修飾符會阻止其他類從該類繼承。
    sealed class A
    {
        int test;
        public void Sum(int i,int j)
        {
            int sum = i + j;
            Console.WriteLine("I am A ,my sum ={0}",sum);
        }
    }
    class B : A 
    {
        public void Minus(int i,int j)
        {
            int minus = i - j;
            Console.WriteLine("I am B ,my minus ={0}", minus);
            this.Sum(3, 4);       //編譯器會報錯    
        }
     }

 前面說過,派生類隱式獲得基類的除構造函數和析構函數以外的所有成員。
 那麼我們該如何獲得基類的構造函數和自身的構造函數呢?
 我們知道基類的初始化工作由基類的構造函數完成,派生類的初始化工作則有派生類的構造函數完成,
但是這樣就產生了派生類構造函數的執行順序問題。
當基類沒有構造函數,派生類也沒有構造函數時,派生類新曾成員的初始化工作由其他公有函數來完成。

 public  class A
    {
        int test=0;
        public void sum()
        {
            test++;
            Console.WriteLine("I am test ={0}" ,test);
        }
    }
    class B : A 
    {
        int i;
        public void PrintInt()
        {
            i = 3;
            Console.WriteLine("I am i ={0}", i);
        }
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.PrintInt();
            Console.Read();
        }
    }

結果:I am i=3

 

如果只有派生類定義構造函數時,只需構造派生類對象即可。對象的基類部分使用默認構造函數來自動創建。當基類和派生類都定義有構造函數時,那麼執行順序會怎樣呢?
如果基類中是沒有參數的構造函數,那麼他可以隱式的被派生類執行,也就是說,派生類根本不需要包含構造函數
如果基類中是沒有參數的構造函數,在派生類中可以自定義有參數的構造函數public  class A
    {
        int test=0;
        public A()
        {
            test = 5;
            Console.WriteLine("I am A 公有默認構造函數 ,test={0}", test);
        }
    }
    class B : A 
    {
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B();
            Console.Read();
        }
    }

結果:I am A 公有默認構造函數 ,test=5

由此可以看見,基類的構造函數被執行,在派生類中被調用。
如果基類定義了帶有參數的構造函數,那麼此構造函數必須被執行,且在派生類中實現該構造函數,此時我們可以使用base關鍵字
    class A
    {
        int test=0;
        public A(int i)
        {
            test = i;
            Console.WriteLine("I am A 公有有參構造函數 ,test={0}", test);
        }
    }
    class B : A 
    {
        public B(int j):base(j)
        {
            Console.WriteLine("I am B 公有有參構造函數,j={0}",j);
        }
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B(1);
            Console.Read();
        }
    }

結果:I am A 公有有參構造函數 ,test=1    

     I am B 公有有參構造函數,j=1

 

由此可見: 派生類隱式執行基類中帶有參數的構造函數,在程序中基類定義了帶有參數的構造函數,
在其派生類中被繼承,並使用base關鍵字調用基類中的構造函數來傳送參數。 我們可以從代碼中看到在創建派生類的對象後,程序首先運行的是基類的構造函數中的內容,然後才是派生類中的內容。如果派生類的基類也是派生類,則每個派生類只需負責其直接基類的構造,不負責間接基類的構造
並且其執行構造函數的順序是從最上面的基類開始的,直到最後一個派生類結束。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved