1. 程式人生 > >補習:C# 面向物件三大特性:封裝、繼承、多型

補習:C# 面向物件三大特性:封裝、繼承、多型

C# 面向物件三大基本特性

封裝、繼承、多型

1、封裝
隱藏物件的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀取和修改的訪問級別。

C# 封裝根據具體的需要,設定使用者的訪問許可權,並通過 訪問修飾符 來實現。

一個 訪問修飾符 定義了一個類成員的範圍和可見性。C# 支援的訪問修飾符如下所示:

● public:所有物件都可以訪問;
● private:物件本身在物件內部可以訪問;
● protected:只有該類物件及其子類物件可以訪問;但不可以繼承給子類
● internal:同一個程式集的物件可以訪問;
● protected internal:訪問限於當前程式集或派生自包含類的型別。

讀寫性

只讀 readonly : {get;}
只寫 writeonly : {set;}
讀寫 read-write : {get;set;}

2、繼承

繼承有一個很重要的原則,叫里氏替換原則:子類是父類;
如:
麻雀:鳥(麻雀繼承鳥類),可以說,麻雀是鳥,但不能說鳥是麻雀。

在程式碼裡也一樣。

//前提:Eagle:Bird
var lstBird = new List<Bird>();
Eagle b1 = new Eagle();
lstBird.Add(b1);//是沒毛病的

因為Eagle是Bird,所以List< Bird> 可以新增Eagle。Eagle擁有所有Bird需要的成員,包括private成員。

實際上,子類能繼承父類除了建構函式以外的所有成員,public\protected\private等,與繼承沒有關係,僅是訪問的可見性。子類能繼承父類成員訪問性的所有特性。但對於private,又有比較特殊的地方:子類無法訪問到父類的private成員,也就是說在子類新建一個同名的成員,編輯器是不會提示重名的。但是實際上父類的private成員是被繼承了的,只不過子類無法看到而已。如父類有一個private成員Color,如果父類的函式有一個WriteLine這個成員的函式,如果子類不重寫此函式,輸出是父類的Color;如果子類重寫了,就算函式內容完全一致,輸出的也是子類的Color;

父類的屬性、方法會繼承給子類,子類中可以訪問直接訪問public\internal的成員,但是無法直接訪問private的成員。對於protected修飾的成員,只有在自己的作用範圍內訪問到protected的成員

。也就是說,只有在程式碼Class {——–}內部,可以直接訪問到protected成員,而當你在例項化類 時,你就不可以訪問該成員了。
同理也繼承到了子類處。

class Bird
    {
        public Bird(string sName,int sSize)
        {
            Name = sName;
            Size = sSize;
        }

        protected string Name;

        public int Size;

        public virtual void Cry()
        {
            Console.WriteLine("i am Bird");
        }

        public void GetName()
        {
            Console.WriteLine(Name);
        }
    }

    class Eagle : Bird
    {
        public Eagle(string Name, int Size) : base(sName: Name, sSize: Size){}

        public override void Cry()
        {
            Console.WriteLine($"i am {Name} !  come ,chickens");
        }
   }    

在Eagle類的內部,重寫了Cry方法,可以直接訪問到繼承的protected成員Name。
而在

class Program
    {
        static void Main(string[] args)
        {
             var b1 = new Eagle("Huge",75);
             var b1Name = b1.Name;
        }
    }

在上述程式碼中則會報錯:
這裡寫圖片描述
僅能在內部訪問,例項化後的成員不可訪問。

3、多型

簡單來說,多型指同一個實體同時具有多種形式。

重寫 是多型的一個重要形式。

父類有一個virtual的方法,則子類可以繼承並重寫這個方法。

這裡寫圖片描述

我舉個例子。

  class Program
    {
        static void Main(string[] args)
        {
            var birdList = new List<Bird>();

            var b1 = new Eagle("Huge",75);

            var b2 = new Sparrow("Tiny", 12);
            birdList.Add(b2);

            birdList.Add(b1);

            foreach (var b in birdList)
            {
                b.Cry();
            }
            Console.Read();
        }

    }


    class Bird
    {
        public Bird(string sName,int sSize)
        {
            Name = sName;
            Size = sSize;
        }

        protected string Name;

        public int Size;

        public virtual void Cry()
        {
            Console.WriteLine("i am Bird");
        }

        public void GetName()
        {
            Console.WriteLine(Name);
        }
    }

    class Eagle : Bird
    {
        public Eagle(string Name, int Size) : base(sName: Name, sSize: Size){}

        public override void Cry()
        {
            Console.WriteLine($"i am {Name} !  come ,chickens");         
        }

    }

    class Sparrow : Bird
    {
        public Sparrow(string Name, int Size) : base(sName: Name, sSize: Size) { }

        public override void Cry()
        {
            Console.WriteLine($"i am  {Name} ! ");
        }
    }

操作結果如下:
這裡寫圖片描述

即:不同的基類的同名方法實現了不同的操作,這就是重寫,多型的體現。

多型還有其他體現方式,下回再補充。

補充一下:過載
過載與重寫不同,過載是同名方法不同引數而體現出不同的操作,建構函式就是一個例子。一個類可以有多個建構函式,引數型別、引數個數成為區別函式主體的條件。