国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

深入理解OOP(第一天):多態和繼承(初期綁定和編譯時多態)

2019-11-14 13:37:18
字體:
來源:轉載
供稿:網友

在本系列中,我們以CodePRoject上比較火的OOP系列博客為主,進行OOP深入淺出展現。

無論作為軟件設計的高手、或者菜鳥,對于架構設計而言,均需要多次重構、取舍,以有利于整個軟件項目的健康構建,有些經驗是前輩總結的,我們拿來使用即可,有些是團隊知識沉淀的,總之復用前人好的思想有利于減少返工。當然,在面試的時候,如果能圍繞OOP大談特談,自然會加分多多的。

開始閱讀本系列博客的預備知識,多態、封裝、面向對象編程等,請通過MSDN學習。如下圖的術語,您應該耳熟能詳的。本系列文章使用C#作為唯一編程語言。

  • 深入理解OOP(一):多態和繼承(初期綁定和編譯時多態)

  • 深入理解OOP(二):多態和繼承(繼承)

  • 深入理解OOP(三):多態和繼承(動態綁定和運行時多態)

  • 深入理解OOP(四):多態和繼承(C#中的抽象類)

  • 深入理解OOP(五):C#中的訪問修飾符(Public/Private/Protected/Internal/Sealed/Constants/Static and Readonly Fields)

  • 深入理解OOP(六):枚舉(實用方法)

  • 深入理解OOP(七):屬性(實用方法)

  • 深入理解OOP(八):索引器(實用方法)

  • 深入理解OOP(九):事件(深入理解)

OOP

是什么OOP,以及OOP的優勢是什么?

OOP代表的是面向對象編程(Object-Oriented Programming),它基于對象的整體進行編程,取代了基于過程函數的編程思想。具體實現是圍繞對象進行數據、函數封裝,而不是基于邏輯關系。OOP中的對象直達的是一個特定的類型、或者某類型的實例對象、更多時候是一個class。每個class對象的結構基本相似,但是有各自特有的屬性和數據值。對象之間可通過對外的接口進行訪問:方法、屬性等。基于OOP的這些優勢,獨立的對象可以修改而不會影響到其他對象,這樣會比較方便的升級軟件減少潛在的bug。軟件系統隨著時間的推移,會變得越來越大,OOP編程思想有效的提高了系統代碼的可讀性和管理性。

OOP的概念是什么?

下面用5個術語來說明OOP的具體概念是什么:

  • 數據抽象(Data Abstraction):數據抽象是對需要操作的物體進行建模的出發點,既對使用對象進行了抽象,隱藏了內部的細節(對使用的最終用戶而言)。用戶可以非常方便的使用class的方法、數據,而不用關心數據創建、運行邏輯的背后復雜的過程。我們以真實世界為例,當你騎一輛自行車的時候,不用考慮變速齒輪的原理如何驅動鏈條、車輪吧。
  • 繼承(Inheritance):繼承是OOP概念中最流行的一個概念。繼承給程序員提供了可復用代碼的優勢。基類定義好函數邏輯,子類通過繼承,可實現直接訪問--就想子類自身的方法一樣方便。
  • 數據封裝(Data Encapsulation):對class的成員變量、成員函數通過訪問控制符進行包裝,則稱為數據封裝。訪問控制符有public、Protected、Private、Internal 4種類型。
  • 多態(Polymorphism):對象可通過傳遞不同參數實現相同的動作,這種行為我們稱之為多態。我們以真實世界為例,“開車”這個方法,對不同類型的用戶要提供不同的參數實現多態,如Car.Drive(Man), Car.Drive(Woman)等。
  • 消息通信(Message Communication):消息通信意味著通過通過消息進行class函數的調用、執行。

多態(Polymorphism)

在本節,我們分別用代碼片段來闡述各自類型的多態類型:函數重載、早期綁定、編譯器的多態。

先創建一個console 工程,并命名為InheritanceAndPolymorphism,然后添加類Overload.cs,再添加DisplayOverload函數。

public class Overload    {        public void DisplayOverload(int a){            System.Console.WriteLine("DisplayOverload " + a);        }        public void DisplayOverload(string a){            System.Console.WriteLine("DisplayOverload " + a);        }        public void DisplayOverload(string a, int b){            System.Console.WriteLine("DisplayOverload " + a + b);        }    }

Program.cs添加如下代碼

class Program{        static void Main(string[] args)        {            Overload overload = new Overload();            overload.DisplayOverload(100);            overload.DisplayOverload("method overloading");            overload.DisplayOverload("method overloading", 100);            Console.ReadKey();        }}

運行程序,結果如下:

 DisplayOverload 100 
DisplayOverload method overloading 
DisplayOverload method overloading100

Overload類中的DisplayOverload提供了3類不同的重載函數:方法名相同,參數類型和個數不同。C#中的這種方式成為重載,既我們不需要為每類函數定義不同名字的函數,僅需要改變函數參數類型和個數即可實現,這個也成為函數簽名。

用不同的返回值可以否? 我們試試下面的代碼:

public void DisplayOverload() { }public int DisplayOverload(){ }

肯定的結果是,Visual Studio會給予如下的報錯信息:

 Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types

從上面的結果可知:返回值不作為多態函數簽名。

我們再運行如下的代碼:

static void DisplayOverload(int a)  {   }public void DisplayOverload(int a) {   }public void DisplayOverload(string a){  }

結果依然是報錯:

Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types

結論:static的可見函數修飾符不作為重載簽名。

運行下面的代碼,試試out、ref可否作為重載簽名。

private void DisplayOverload(int a) {   }private void DisplayOverload(out int a)        {            a = 100;        }private void DisplayOverload(ref int a) {   }

結果是如下的報錯:

Error: Cannot define overloaded method 'DisplayOverload' because it differs from another method only on ref and out

結論:ref、out傳遞參數修飾符也不能作為重載簽名。


多態中Params 參數的作用

一個函數可包含如下4種類型的參數傳遞:

  • 值傳遞 (pass by value)
  • 引用傳遞 (Pass by reference)
  • 作為output參數 (As an output parameter)
  • 使用參數數組 (Using parameter arrays)

我們運行如下代碼:

public void DisplayOverload(int a, string a)  {   }        public void Display(int a)        {            string a;        }

獲得如下報錯信息:

Error1: The parameter name 'a' is a duplicate

Error2: A local variable named 'a' cannot be declared in this scope because it would give a different meaning to 'a', which is already used in a 'parent or current' scope to denote something else

在相同的作用域中,參數名稱必須是唯一的。

在Overload.cs文件中,添加如下代碼:

public class Overload    {        private string name = "Akhil";        public void Display()        {            Display2(ref name, ref name);            System.Console.WriteLine(name);        }        private void Display2(ref string x, ref string y)        {            System.Console.WriteLine(name);            x = "Akhil 1";            System.Console.WriteLine(name);            y = "Akhil 2";            System.Console.WriteLine(name);            name = "Akhil 3";        }    }

在Program.cs中添加如下代碼:

class Program    {        static void Main(string[] args)        {            Overload overload = new Overload();            overload.Display();            Console.ReadKey();        }    }

運行結果如下:

Akhil 
Akhil 1 
Akhil 2 
Akhil3

結論:我們通過ref引用傳遞了name的內存地址,故修改x、y的值相當于直接修改name的值,故結果運行如上。

 

下面這段代碼演示了params關鍵字的作用:

在Overload.cs文件添加如下代碼:

public class Overload    {        public void Display()        {            DisplayOverload(100, "Akhil", "Mittal", "OOP");            DisplayOverload(200, "Akhil");            DisplayOverload(300);        }        private void DisplayOverload(int a, params string[] parameterArray)        {            foreach (string str in parameterArray)               Console.WriteLine(str + " " + a);        }    }

在Program.cs文件添加如下代碼:

class Program    {        static void Main(string[] args)        {            Overload overload = new Overload();            overload.Display();            Console.ReadKey();        }    }

運行結果如下:

Akhil 100 
Mittal 100 
OOP 100 
Akhil 200

C#提供了params動態參數數組機制,非常方便的在運行時動態傳遞不同數量的同類型參數。

注:params關鍵詞僅能作為函數的最后一個參數適用。

 

我們再試試params關鍵字的函數簽名和非params關鍵字函數簽名的優先級順序:

public class Overload    {        public void Display()        {            DisplayOverload(200);            DisplayOverload(200, 300);            DisplayOverload(200, 300, 500, 600);        }        private void DisplayOverload(int x, int y)        {            Console.WriteLine("The two integers " + x + " " + y);        }        private void DisplayOverload(params int[] parameterArray)        {            Console.WriteLine("parameterArray");        }    }

Program.cs文件添加如下代碼:

class Program    {        static void Main(string[] args)        {            Overload overload = new Overload();            overload.Display();            Console.ReadKey();        }    }

運行結果如下:

parameterArray 
The two integers 200 300 
parameterArray

從運行結果看,C#非常巧妙的進行非params函數的精準匹配優先,如1個int類型/3個int類型,則用params類型匹配;2個int類型,用明確定義的函數進行匹配。

 

結論

在本節中,我們進行OOP系列的第一篇,主要說明了編譯器的多態,它也稱為早期綁定或者方法重載。同時,我們也學習C#中威力強大的params關鍵字,并用它來實現多態。

本文要點歸納如下:

  • C#函數重載的簽名規則是用參數的類型和數量判斷,而不是函數的名字。
  • 函數返回值不作為重載簽名。
  • 修飾符不作為簽名的一部分,如static
  • 同函數中,多個參數名稱要唯一
  • ref、out是引用傳遞,傳遞的是參數的內存地址
  • params 作為參數關鍵詞,僅能用于函數的最后一個參數

 

原文地址:http://www.codeproject.com/Articles/771455/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear

譯文地址:http://m.survivalescaperooms.com/powertoolsteam/p/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳城县| 丹东市| 兴海县| 台湾省| 静安区| 永德县| 天台县| 汉阴县| 获嘉县| 龙游县| 罗平县| 永泰县| 内黄县| 安乡县| 佛山市| 广灵县| 牟定县| 荔波县| 钟山县| 弥勒县| 梅河口市| 浦北县| 诸暨市| 堆龙德庆县| 湛江市| 长宁县| 柳林县| 蒙山县| 达日县| 乐昌市| 隆回县| 绵阳市| 加查县| 新丰县| 苏尼特右旗| 元氏县| 广德县| 喜德县| 太仆寺旗| 石棉县| 阳山县|