久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

?? 學(xué)會編程入門必備 C# 最基礎(chǔ)知識介紹(五)——方法,、封裝、繼承,、多態(tài)

 敲代碼的小Y 2021-12-01

前言??

學(xué)過編程的人都知道有個名詞叫 " O O P 思 想 " \color{FF66FF}{"OOP思想"} "OOP" —— " 面 向 對 象 編 程 " \color{FF66FF}{"面向?qū)ο缶幊?quot;} ""(Object Oriented Programming,,OOP,,面向?qū)ο蟪绦蛟O(shè)計)是一種計算機編程架構(gòu)。OOP 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或?qū)ο蠼M合而成,。OOP 達到了軟件工程的三個主要目標:重用性,、靈活性和擴展性。為了實現(xiàn)整體運算,,每個對象都能夠接收信息,、處理數(shù)據(jù)和向其它對象發(fā)送信息
核心思想:封裝,繼承,,多態(tài).

前面幾篇博客介紹了C#的一些基礎(chǔ)知識,,包括基本語法、運算符,、數(shù)組等,。
在本篇博客就來介紹在C#中最常用的幾種概念,即: 方 法 \color{0000ff}{方法} ,、 繼 承 \color{00ff00}{繼承} ,、 封 裝 \color{00ff00}{封裝} 、 多 態(tài) \color{00ff00}{多態(tài)} 態(tài)


方法??

一個方法是把一些相關(guān)的語句組織在一起,,用來執(zhí)行一個任務(wù)的語句塊,。每一個 C# 程序至少有一個帶有 Main 方法的類。
要使用一個方法,,您需要:

  • 定義方法

  • 調(diào)用方法


C# 中定義方法

當定義一個方法時,,從根本上說是在聲明它的結(jié)構(gòu)的元素。在 C# 中,,定義方法的語法如下:

<Access Specifier> <Return Type> <Method Name>(Parameter List){
   Method Body}

下面是方法的各個元素:

  • Access Specifier:訪問修飾符,,這個決定了變量或方法對于另一個類的可見性。

  • Return type:返回類型,,一個方法可以返回一個值。返回類型是方法返回的值的數(shù)據(jù)類型,。如果方法不返回任何值,,則返回類型為 void。

  • Method name:方法名稱,,是一個唯一的標識符,,且是大小寫敏感的。它不能與類中聲明的其他標識符相同,。

  • Parameter
    list:參數(shù)列表,,使用圓括號括起來,該參數(shù)是用來傳遞和接收方法的數(shù)據(jù),。參數(shù)列表是指方法的參數(shù)類型,、順序和數(shù)量。參數(shù)是可選的,也就是說,,一個方法可能不包含參數(shù),。

  • Method body:方法主體,包含了完成任務(wù)所需的指令集,。

實例

下面的代碼片段顯示一個函數(shù) FindMax,,它接受兩個整數(shù)值,并返回兩個中的較大值,。它有 public 訪問修飾符,,所以它可以使用類的實例從類的外部進行訪問。

實例class NumberManipulator{
   public int FindMax(int num1, int num2)
   {
      /* 局部變量聲明 */
      int result;

      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result;
   }}

C# 中調(diào)用方法

您可以使用方法名調(diào)用方法,。下面的實例演示了這點:

實例using System;namespace CalculatorApplication{
   class NumberManipulator
   {
      public int FindMax(int num1, int num2)
      {
         /* 局部變量聲明 */
         int result;

         if (num1 > num2)
            result = num1;
         else
            result = num2;

         return result;
      }
      static void Main(string[] args)
      {
         /* 局部變量定義 */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();

         //調(diào)用 FindMax 方法
         ret = n.FindMax(a, b);
         Console.WriteLine("最大值是: {0}", ret );
         Console.ReadLine();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

最大值是: 200

也可以使用類的實例從另一個類中調(diào)用其他類的公有方法。例如,,方法 FindMax 屬于 NumberManipulator 類,,可以從另一個類 Test 中調(diào)用它。

using System;namespace CalculatorApplication{
    class NumberManipulator
    {
        public int FindMax(int num1, int num2)
        {
            /* 局部變量聲明 */
            int result;

            if (num1 > num2)
                result = num1;
            else
                result = num2;

            return result;
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            /* 局部變量定義 */
            int a = 100;
            int b = 200;
            int ret;
            NumberManipulator n = new NumberManipulator();
            //調(diào)用 FindMax 方法
            ret = n.FindMax(a, b);
            Console.WriteLine("最大值是: {0}", ret );
            Console.ReadLine();

        }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

最大值是: 200


遞歸方法調(diào)用

一個方法可以自我調(diào)用,。這就是所謂的 遞歸。下面的實例使用遞歸函數(shù)計算一個數(shù)的階乘:

實例using System;namespace CalculatorApplication{
    class NumberManipulator
    {
        public int factorial(int num)
        {
            /* 局部變量定義 */
            int result;

            if (num == 1)
            {
                return 1;
            }
            else
            {
                result = factorial(num - 1) * num;
                return result;
            }
        }
   
        static void Main(string[] args)
        {
            NumberManipulator n = new NumberManipulator();
            //調(diào)用 factorial 方法
            Console.WriteLine("6 的階乘是: {0}", n.factorial(6));
            Console.WriteLine("7 的階乘是: {0}", n.factorial(7));
            Console.WriteLine("8 的階乘是: {0}", n.factorial(8));
            Console.ReadLine();

        }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

6 的階乘是: 720
7 的階乘是: 5040
8 的階乘是: 40320


參數(shù)傳遞

當調(diào)用帶有參數(shù)的方法時,,您需要向方法傳遞參數(shù)。在 C# 中,,有三種向方法傳遞參數(shù)的方式

方式描述
值參數(shù)這種方式復(fù)制參數(shù)的實際值給函數(shù)的形式參數(shù),,實參和形參使用的是兩個不同內(nèi)存中的值。在這種情況下,,當形參的值發(fā)生改變時,,不會影響實參的值,從而保證了實參數(shù)據(jù)的安全,。
引用參數(shù)這種方式復(fù)制參數(shù)的內(nèi)存位置的引用給形式參數(shù),。這意味著,當形參的值發(fā)生改變時,,同時也改變實參的值,。
輸出參數(shù)這種方式可以返回多個值。

按值傳遞參數(shù)

這是參數(shù)傳遞的默認方式,。在這種方式下,,當調(diào)用一個方法時,會為每個值參數(shù)創(chuàng)建一個新的存儲位置,。

實際參數(shù)的值會復(fù)制給形參,,實參和形參使用的是兩個不同內(nèi)存中的值,。所以,當形參的值發(fā)生改變時,,不會影響實參的值,,從而保證了實參數(shù)據(jù)的安全。下面的實例演示了這個概念:

實例using System;namespace CalculatorApplication{
   class NumberManipulator
   {
      public void swap(int x, int y)
      {
         int temp;
         
         temp = x; /* 保存 x 的值 */
         x = y;    /* 把 y 賦值給 x */
         y = temp; /* 把 temp 賦值給 y */
      }
     
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部變量定義 */
         int a = 100;
         int b = 200;
         
         Console.WriteLine("在交換之前,,a 的值: {0}", a);
         Console.WriteLine("在交換之前,,b 的值: {0}", b);
         
         /* 調(diào)用函數(shù)來交換值 */
         n.swap(a, b);
         
         Console.WriteLine("在交換之后,a 的值: {0}", a);
         Console.WriteLine("在交換之后,,b 的值: {0}", b);
         
         Console.ReadLine();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

在交換之前,a 的值:100
在交換之前,,b 的值:200
在交換之后,,a 的值:100
在交換之后,b 的值:200

結(jié)果表明,,即使在函數(shù)內(nèi)改變了值,,值也沒有發(fā)生任何的變化。

按引用傳遞參數(shù)

引用參數(shù)是一個對變量的內(nèi)存位置的引用,。當按引用傳遞參數(shù)時,,與值參數(shù)不同的是,它不會為這些參數(shù)創(chuàng)建一個新的存儲位置,。引用參數(shù)表示與提供給方法的實際參數(shù)具有相同的內(nèi)存位置,。

在 C# 中,使用 按引用傳遞參數(shù)
引用參數(shù)是一個對變量的內(nèi)存位置的引用,。當按引用傳遞參數(shù)時,,與值參數(shù)不同的是,它不會為這些參數(shù)創(chuàng)建一個新的存儲位置,。引用參數(shù)表示與提供給方法的實際參數(shù)具有相同的內(nèi)存位置,。

在 C# 中,使用 ref 關(guān)鍵字聲明引用參數(shù),。下面的實例演示了這點:

實例using System;namespace CalculatorApplication{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;

         temp = x; /* 保存 x 的值 */
         x = y;    /* 把 y 賦值給 x */
         y = temp; /* 把 temp 賦值給 y */
       }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部變量定義 */
         int a = 100;
         int b = 200;

         Console.WriteLine("在交換之前,,a 的值: {0}", a);
         Console.WriteLine("在交換之前,b 的值: {0}", b);

         /* 調(diào)用函數(shù)來交換值 */
         n.swap(ref a, ref b);

         Console.WriteLine("在交換之后,,a 的值: {0}", a);
         Console.WriteLine("在交換之后,,b 的值: {0}", b);
 
         Console.ReadLine();

      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

在交換之前,,a 的值:100
在交換之前,b 的值:200
在交換之后,,a 的值:200
在交換之后,,b 的值:100

結(jié)果表明,,swap 函數(shù)內(nèi)的值改變了,且這個改變可以在 Main 函數(shù)中反映出來,。

按輸出傳遞參數(shù)

return 語句可用于只從函數(shù)中返回一個值,。但是,可以使用 輸出參數(shù) 來從函數(shù)中返回兩個值,。輸出參數(shù)會把方法輸出的數(shù)據(jù)賦給自己,,其他方面與引用參數(shù)相似。

下面的實例演示了這點:

實例using System;namespace CalculatorApplication{
   class NumberManipulator
   {
      public void getValue(out int x )
      {
         int temp = 5;
         x = temp;
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部變量定義 */
         int a = 100;
         
         Console.WriteLine("在方法調(diào)用之前,,a 的值: {0}", a);
         
         /* 調(diào)用函數(shù)來獲取值 */
         n.getValue(out a);

         Console.WriteLine("在方法調(diào)用之后,,a 的值: {0}", a);
         Console.ReadLine();

      }
   }}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

在方法調(diào)用之前,,a 的值: 100
在方法調(diào)用之后,,a 的值: 5

提供給輸出參數(shù)的變量不需要賦值。當需要從一個參數(shù)沒有指定初始值的方法中返回值時,,輸出參數(shù)特別有用,。請看下面的實例,來理解這一點:

實例using System;namespace CalculatorApplication{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("請輸入第一個值: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("請輸入第二個值: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部變量定義 */
         int a , b;
         
         /* 調(diào)用函數(shù)來獲取值 */
         n.getValues(out a, out b);

         Console.WriteLine("在方法調(diào)用之后,,a 的值: {0}", a);
         Console.WriteLine("在方法調(diào)用之后,,b 的值: {0}", b);
         Console.ReadLine();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果(取決于用戶輸入):

請輸入第一個值:
7
請輸入第二個值:
8
在方法調(diào)用之后,,a 的值: 7
在方法調(diào)用之后,,b 的值: 8


C# 封裝??

封裝 被定義為"把一個或多個項目封閉在一個物理的或者邏輯的包中"。在面向?qū)ο蟪绦蛟O(shè)計方法論中,,封裝是為了防止對實現(xiàn)細節(jié)的訪問,。

抽象和封裝是面向?qū)ο蟪绦蛟O(shè)計的相關(guān)特性。抽象允許相關(guān)信息可視化,,封裝則使開發(fā)者實現(xiàn)所需級別的抽象,。

C# 封裝根據(jù)具體的需要,設(shè)置使用者的訪問權(quán)限,,并通過 訪問修飾符 來實現(xiàn),。

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

  • public:所有對象都可以訪問,;

  • private:對象本身在對象內(nèi)部可以訪問,;

  • protected:只有該類對象及其子類對象可以訪問

  • internal:同一個程序集的對象可以訪問;

  • protected internal:訪問限于當前程序集或派生自包含類的類型,。


Public 訪問修飾符

Public 訪問修飾符允許一個類將其成員變量和成員函數(shù)暴露給其他的函數(shù)和對象,。任何公有成員可以被外部的類訪問。

下面的實例說明了這點:

實例using System;namespace RectangleApplication{
    class Rectangle
    {
        //成員變量
        public double length;
        public double width;

        public double GetArea()
        {
            return length * width;
        }
        public void Display()
        {
            Console.WriteLine("長度: {0}", length);
            Console.WriteLine("寬度: {0}", width);
            Console.WriteLine("面積: {0}", GetArea());
        }
    }// Rectangle 結(jié)束

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

長度: 4.5
寬度: 3.5
面積: 15.75

在上面的實例中,,成員變量 length 和 width 被聲明為 public,,所以它們可以被函數(shù) Main() 使用 Rectangle 類的實例 r 訪問。
成員函數(shù) Display() 和 GetArea() 可以直接訪問這些變量,。
成員函數(shù) Display() 也被聲明為 public,,所以它也能被 Main() 使用 Rectangle 類的實例 r 訪問。


Private 訪問修飾符

Private 訪問修飾符允許一個類將其成員變量和成員函數(shù)對其他的函數(shù)和對象進行隱藏,。只有同一個類中的函數(shù)可以訪問它的私有成員,。即使是類的實例也不能訪問它的私有成員。

下面的實例說明了這點:

實例using System;namespace RectangleApplication{
    class Rectangle
    {
        //成員變量
        private double length;
        private double width;

        public void Acceptdetails()
        {
            Console.WriteLine("請輸入長度:");
            length = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("請輸入寬度:");
            width = Convert.ToDouble(Console.ReadLine());
        }
        public double GetArea()
        {
            return length * width;
        }
        public void Display()
        {
            Console.WriteLine("長度: {0}", length);
            Console.WriteLine("寬度: {0}", width);
            Console.WriteLine("面積: {0}", GetArea());
        }
    }//end class Rectangle    
    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.Acceptdetails();
            r.Display();
            Console.ReadLine();
        }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

請輸入長度:
4.4
請輸入寬度:
3.3

長度: 4.4
寬度: 3.3
面積: 14.52

在上面的實例中,,成員變量 length 和 width 被聲明為 private,所以它們不能被函數(shù) Main() 訪問,。
成員函數(shù) AcceptDetails() 和 Display() 可以訪問這些變量,。
由于成員函數(shù) AcceptDetails() 和 Display() 被聲明為 public,所以它們可以被 Main() 使用 Rectangle 類的實例 r 訪問,。


Protected 訪問修飾符

Protected 訪問修飾符允許子類訪問它的基類的成員變量和成員函數(shù),。這樣有助于實現(xiàn)繼承。將在繼承的內(nèi)容部分詳細討論這個,。


Internal 訪問修飾符

Internal 訪問說明符允許一個類將其成員變量和成員函數(shù)暴露給當前程序中的其他函數(shù)和對象,。換句話說,帶有 internal 訪問修飾符的任何成員可以被定義在該成員所定義的應(yīng)用程序內(nèi)的任何類或方法訪問,。

下面的實例說明了這點:

實例using System;namespace RectangleApplication{
    class Rectangle
    {
        //成員變量
        internal double length;
        internal double width;
       
        double GetArea()
        {
            return length * width;
        }
       public void Display()
        {
            Console.WriteLine("長度: {0}", length);
            Console.WriteLine("寬度: {0}", width);
            Console.WriteLine("面積: {0}", GetArea());
        }
    }//end class Rectangle    
    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

長度: 4.5
寬度: 3.5
面積: 15.75

在上面的實例中,請注意成員函數(shù) GetArea() 聲明的時候不帶有任何訪問修飾符,。如果沒有指定訪問修飾符,,則使用類成員的默認訪問修飾符,即為 private,。


Protected Internal 訪問修飾符

Protected Internal 訪問修飾符允許在本類,派生類或者包含該類的程序集中訪問,。這也被用于實現(xiàn)繼承。


C# 繼承??

繼承是面向?qū)ο蟪绦蛟O(shè)計中最重要的概念之一,。繼承允許我們根據(jù)一個類來定義另一個類,,這使得創(chuàng)建和維護應(yīng)用程序變得更容易。同時也有利于重用代碼和節(jié)省開發(fā)時間,。

當創(chuàng)建一個類時,,程序員不需要完全重新編寫新的數(shù)據(jù)成員和成員函數(shù),只需要設(shè)計一個新的類,,繼承了已有的類的成員即可,。這個已有的類被稱為的基類,這個新的類被稱為派生類

繼承的思想實現(xiàn)了 屬于 (IS-A) 關(guān)系,。例如,哺乳動物 屬于 (IS-A) 動物,,狗 屬于 (IS-A) 哺乳動物,,因此狗 屬于 (IS-A) 動物。

基類和派生類

一個類可以派生自多個類或接口,,這意味著它可以從多個基類或接口繼承數(shù)據(jù)和函數(shù),。

C# 中創(chuàng)建派生類的語法如下:

<訪問修飾符符> class <基類>{
 ...}class <派生類> : <基類>{
 ...}

假設(shè),有一個基類 Shape,,它的派生類是 Rectangle:

實例using System;namespace InheritanceApplication{
   class Shape
   {
      public void setWidth(int w)
      {
         width = w;
      }
      public void setHeight(int h)
      {
         height = h;
      }
      protected int width;
      protected int height;
   }

   // 派生類
   class Rectangle: Shape
   {
      public int getArea()
      {
         return (width * height);
      }
   }
   
   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle Rect = new Rectangle();

         Rect.setWidth(5);
         Rect.setHeight(7);

         // 打印對象的面積
         Console.WriteLine("總面積: {0}",  Rect.getArea());
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

總面積: 35


基類的初始化

派生類繼承了基類的成員變量和成員方法。因此父類對象應(yīng)在子類對象創(chuàng)建之前被創(chuàng)建,。您可以在成員初始化列表中進行父類的初始化,。

下面的程序演示了這點:

實例using System;namespace RectangleApplication{
   class Rectangle
   {
      // 成員變量
      protected double length;
      protected double width;
      public Rectangle(double l, double w)
      {
         length = l;
         width = w;
      }
      public double GetArea()
      {
         return length * width;
      }
      public void Display()
      {
         Console.WriteLine("長度: {0}", length);
         Console.WriteLine("寬度: {0}", width);
         Console.WriteLine("面積: {0}", GetArea());
      }
   }//end class Rectangle  
   class Tabletop : Rectangle
   {
      private double cost;
      public Tabletop(double l, double w) : base(l, w)
      { }
      public double GetCost()
      {
         double cost;
         cost = GetArea() * 70;
         return cost;
      }
      public void Display()
      {
         base.Display();
         Console.WriteLine("成本: {0}", GetCost());
      }
   }
   class ExecuteRectangle
   {
      static void Main(string[] args)
      {
         Tabletop t = new Tabletop(4.5, 7.5);
         t.Display();
         Console.ReadLine();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

長度: 4.5
寬度: 7.5
面積: 33.75
成本: 2362.5


C# 多重繼承

多重繼承指的是一個類別可以同時從多于一個父類繼承行為與特征的功能,。與單一繼承相對,,單一繼承指一個類別只可以繼承自一個父類。

C# 不支持多重繼承,。但是,,您可以使用接口來實現(xiàn)多重繼承。下面的程序演示了這點:

實例using System;namespace InheritanceApplication{
   class Shape
   {
      public void setWidth(int w)
      {
         width = w;
      }
      public void setHeight(int h)
      {
         height = h;
      }
      protected int width;
      protected int height;
   }

   // 基類 PaintCost
   public interface PaintCost
   {
      int getCost(int area);

   }
   // 派生類
   class Rectangle : Shape, PaintCost
   {
      public int getArea()
      {
         return (width * height);
      }
      public int getCost(int area)
      {
         return area * 70;
      }
   }
   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle Rect = new Rectangle();
         int area;
         Rect.setWidth(5);
         Rect.setHeight(7);
         area = Rect.getArea();
         // 打印對象的面積
         Console.WriteLine("總面積: {0}",  Rect.getArea());
         Console.WriteLine("油漆總成本: ${0}" , Rect.getCost(area));
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

總面積: 35
油漆總成本: $2450


C# 多態(tài)性??

多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力,。

多態(tài)性意味著有多重形式。在面向?qū)ο缶幊谭妒街?,多態(tài)性往往表現(xiàn)為"一個接口,,多個功能"。
多態(tài)性可以是靜態(tài)的或動態(tài)的,。在靜態(tài)多態(tài)性中,,函數(shù)的響應(yīng)是在編譯時發(fā)生的。在動態(tài)多態(tài)性中,,函數(shù)的響應(yīng)是在運行時發(fā)生的,。
在 C# 中,每個類型都是多態(tài)的,,因為包括用戶定義類型在內(nèi)的所有類型都繼承自 Object,。
多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作,,如圖所示:
在這里插入圖片描述

現(xiàn)實中,,比如我們按下 F1 鍵這個動作:

  • 如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;

  • 如果當前在 Word 下彈出的就是 Word 幫助;

  • 在 Windows 下彈出的就是 Windows 幫助和支持,。

  • 同一個事件發(fā)生在不同的對象上會產(chǎn)生不同的結(jié)果,。


靜態(tài)多態(tài)性

在編譯時,函數(shù)和對象的連接機制被稱為早期綁定,,也被稱為靜態(tài)綁定,。C# 提供了兩種技術(shù)來實現(xiàn)靜態(tài)多態(tài)性。分別為:

  • 函數(shù)重載

  • 運算符重載


函數(shù)重載

可以在同一個范圍內(nèi)對相同的函數(shù)名有多個定義,。函數(shù)的定義必須彼此不同,,可以是參數(shù)列表中的參數(shù)類型不同,也可以是參數(shù)個數(shù)不同,。不能重載只有返回類型不同的函數(shù)聲明,。

下面的實例演示了幾個相同的函數(shù) Add(),用于對不同個數(shù)參數(shù)進行相加處理:

實例using System;namespace PolymorphismApplication{
    public class TestData  
    {  
        public int Add(int a, int b, int c)  
        {  
            return a + b + c;  
        }  
        public int Add(int a, int b)  
        {  
            return a + b;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            TestData dataClass = new TestData();
            int add1 = dataClass.Add(1, 2);  
            int add2 = dataClass.Add(1, 2, 3);

            Console.WriteLine("add1 :" + add1);
            Console.WriteLine("add2 :" + add2);  
        }  
    }  }

下面的實例演示了幾個相同的函數(shù) print(),,用于打印不同的數(shù)據(jù)類型:

實例using System;namespace PolymorphismApplication{
   class Printdata
   {
      void print(int i)
      {
         Console.WriteLine("輸出整型: {0}", i );
      }

      void print(double f)
      {
         Console.WriteLine("輸出浮點型: {0}" , f);
      }

      void print(string s)
      {
         Console.WriteLine("輸出字符串: {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // 調(diào)用 print 來打印整數(shù)
         p.print(1);
         // 調(diào)用 print 來打印浮點數(shù)
         p.print(1.23);
         // 調(diào)用 print 來打印字符串
         p.print("Hello Runoob");
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

輸出整型: 1
輸出浮點型: 1.23
輸出字符串: Hello Runoob


C# 運算符重載

您可以重定義或重載 C# 中內(nèi)置的運算符。因此,,程序員也可以使用用戶自定義類型的運算符,。重載運算符是具有特殊名稱的函數(shù),是通過關(guān)鍵字 operator 后跟運算符的符號來定義的,。與其他函數(shù)一樣,,重載運算符有返回類型和參數(shù)列表。

例如,,請看下面的函數(shù):

public static Box operator+ (Box b, Box c){
   Box box = new Box();
   box.length = b.length + c.length;
   box.breadth = b.breadth + c.breadth;
   box.height = b.height + c.height;
   return box;}

上面的函數(shù)為用戶自定義的類 Box 實現(xiàn)了加法運算符(+),。它把兩個 Box 對象的屬性相加,并返回相加后的 Box 對象,。


運算符重載的實現(xiàn)

下面的程序演示了完整的實現(xiàn):

實例using System;namespace OperatorOvlApplication{
   class Box
   {
      private double length;      // 長度
      private double breadth;     // 寬度
      private double height;      // 高度

      public double getVolume()
      {
         return length * breadth * height;
      }
      public void setLength( double len )
      {
         length = len;
      }

      public void setBreadth( double bre )
      {
         breadth = bre;
      }

      public void setHeight( double hei )
      {
         height = hei;
      }
      // 重載 + 運算符來把兩個 Box 對象相加
      public static Box operator+ (Box b, Box c)
      {
         Box box = new Box();
         box.length = b.length + c.length;
         box.breadth = b.breadth + c.breadth;
         box.height = b.height + c.height;
         return box;
      }

   }

   class Tester
   {
      static void Main(string[] args)
      {
         Box Box1 = new Box();         // 聲明 Box1,,類型為 Box
         Box Box2 = new Box();         // 聲明 Box2,類型為 Box
         Box Box3 = new Box();         // 聲明 Box3,,類型為 Box
         double volume = 0.0;          // 體積

         // Box1 詳述
         Box1.setLength(6.0);
         Box1.setBreadth(7.0);
         Box1.setHeight(5.0);

         // Box2 詳述
         Box2.setLength(12.0);
         Box2.setBreadth(13.0);
         Box2.setHeight(10.0);

         // Box1 的體積
         volume = Box1.getVolume();
         Console.WriteLine("Box1 的體積: {0}", volume);

         // Box2 的體積
         volume = Box2.getVolume();
         Console.WriteLine("Box2 的體積: {0}", volume);

         // 把兩個對象相加
         Box3 = Box1 + Box2;

         // Box3 的體積
         volume = Box3.getVolume();
         Console.WriteLine("Box3 的體積: {0}", volume);
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

Box1 的體積: 210
Box2 的體積: 1560
Box3 的體積: 5400


可重載和不可重載運算符

下表描述了 C# 中運算符重載的能力:

運算符描述
+, -, !, ~, ++, –這些一元運算符只有一個操作數(shù),且可以被重載
+, -, *, /, %這些二元運算符帶有兩個操作數(shù),,且可以被重載
==, !=, <, >, <=, >=這些比較運算符可以被重載
&&,這些條件邏輯運算符不能被直接重載
+=, -=, *=, /=, %=這些賦值運算符不能被重載
=, ., ?:, ->, new, is, sizeof, typeof這些運算符不能被重載

實例
針對上述討論,,讓我們擴展上面的實例,重載更多的運算符:

實例using System;namespace OperatorOvlApplication{
    class Box
    {
       private double length;      // 長度
       private double breadth;     // 寬度
       private double height;      // 高度
     
       public double getVolume()
       {
         return length * breadth * height;
       }
      public void setLength( double len )
      {
          length = len;
      }

      public void setBreadth( double bre )
      {
          breadth = bre;
      }

      public void setHeight( double hei )
      {
          height = hei;
      }
      // 重載 + 運算符來把兩個 Box 對象相加
      public static Box operator+ (Box b, Box c)
      {
          Box box = new Box();
          box.length = b.length + c.length;
          box.breadth = b.breadth + c.breadth;
          box.height = b.height + c.height;
          return box;
      }
     
      public static bool operator == (Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length == rhs.length && lhs.height == rhs.height             && lhs.breadth == rhs.breadth)
          {
              status = true;
          }
          return status;
      }
      public static bool operator !=(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length != rhs.length || lhs.height != rhs.height              || lhs.breadth != rhs.breadth)
          {
              status = true;
          }
          return status;
      }
      public static bool operator <(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length < rhs.length && lhs.height              < rhs.height && lhs.breadth < rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator >(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length > rhs.length && lhs.height              > rhs.height && lhs.breadth > rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator <=(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length <= rhs.length && lhs.height              <= rhs.height && lhs.breadth <= rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator >=(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length >= rhs.length && lhs.height             >= rhs.height && lhs.breadth >= rhs.breadth)
          {
              status = true;
          }
          return status;
      }
      public override string ToString()
      {
          return String.Format("({0}, {1}, {2})", length, breadth, height);
      }
   
   }
   
   class Tester
   {
      static void Main(string[] args)
      {
        Box Box1 = new Box();          // 聲明 Box1,,類型為 Box
        Box Box2 = new Box();          // 聲明 Box2,,類型為 Box
        Box Box3 = new Box();          // 聲明 Box3,類型為 Box
        Box Box4 = new Box();
        double volume = 0.0;   // 體積

        // Box1 詳述
        Box1.setLength(6.0);
        Box1.setBreadth(7.0);
        Box1.setHeight(5.0);

        // Box2 詳述
        Box2.setLength(12.0);
        Box2.setBreadth(13.0);
        Box2.setHeight(10.0);

       // 使用重載的 ToString() 顯示兩個盒子
        Console.WriteLine("Box1: {0}", Box1.ToString());
        Console.WriteLine("Box2: {0}", Box2.ToString());
       
        // Box1 的體積
        volume = Box1.getVolume();
        Console.WriteLine("Box1 的體積: {0}", volume);

        // Box2 的體積
        volume = Box2.getVolume();
        Console.WriteLine("Box2 的體積: {0}", volume);

        // 把兩個對象相加
        Box3 = Box1 + Box2;
        Console.WriteLine("Box3: {0}", Box3.ToString());
        // Box3 的體積
        volume = Box3.getVolume();
        Console.WriteLine("Box3 的體積: {0}", volume);

        //comparing the boxes
        if (Box1 > Box2)
          Console.WriteLine("Box1 大于 Box2");
        else
          Console.WriteLine("Box1 不大于 Box2");
        if (Box1 < Box2)
          Console.WriteLine("Box1 小于 Box2");
        else
          Console.WriteLine("Box1 不小于 Box2");
        if (Box1 >= Box2)
          Console.WriteLine("Box1 大于等于 Box2");
        else
          Console.WriteLine("Box1 不大于等于 Box2");
        if (Box1 <= Box2)
          Console.WriteLine("Box1 小于等于 Box2");
        else
          Console.WriteLine("Box1 不小于等于 Box2");
        if (Box1 != Box2)
          Console.WriteLine("Box1 不等于 Box2");
        else
          Console.WriteLine("Box1 等于 Box2");
        Box4 = Box3;
        if (Box3 == Box4)
          Console.WriteLine("Box3 等于 Box4");
        else
          Console.WriteLine("Box3 不等于 Box4");

        Console.ReadKey();
      }
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

Box1: (6, 7, 5)
Box2: (12, 13, 10)
Box1 的體積: 210
Box2 的體積: 1560
Box3:(18, 20, 15)
Box3 的體積: 5400
Box1 不大于 Box2
Box1 小于 Box2
Box1 不大于等于 Box2
Box1 小于等于 Box2
Box1 不等于 Box2
Box3 等于 Box4


動態(tài)多態(tài)性

C# 允許您使用關(guān)鍵字 abstract 創(chuàng)建抽象類,,用于提供接口的部分類的實現(xiàn)。當一個派生類繼承自該抽象類時,實現(xiàn)即完成,。抽象類包含抽象方法,,抽象方法可被派生類實現(xiàn)。派生類具有更專業(yè)的功能,。

請注意,,下面是有關(guān)抽象類的一些規(guī)則:

  • 不能創(chuàng)建一個抽象類的實例。

  • 不能在一個抽象類外部聲明一個抽象方法,。

  • 通過在類定義前面放置關(guān)鍵字 sealed,可以將類聲明為密封類,。當一個類被聲明為 sealed 時,,它不能被繼承。抽象類不能被聲明為
    sealed,。

下面的程序演示了一個抽象類:

實例using System;namespace PolymorphismApplication{
   abstract class Shape
   {
       abstract public int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0, int b=0)
      {
         length = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine("Rectangle 類的面積:");
         return (width * length);
      }
   }

   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(10, 7);
         double a = r.area();
         Console.WriteLine("面積: {0}",a);
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

Rectangle 類的面積:
面積: 70

當有一個定義在類中的函數(shù)需要在繼承類中實現(xiàn)時,可以使用虛方法,。

虛方法是使用關(guān)鍵字 virtual 聲明的,。

虛方法可以在不同的繼承類中有不同的實現(xiàn)。

對虛方法的調(diào)用是在運行時發(fā)生的,。

動態(tài)多態(tài)性是通過 抽象類虛方法 實現(xiàn)的,。

以下實例創(chuàng)建了 Shape 基類,,并創(chuàng)建派生類 Circle,、 Rectangle、Triangle,, Shape 類提供一個名為 Draw 的虛擬方法,,在每個派生類中重寫該方法以繪制該類的指定形狀,。

實例using System;using System.Collections.Generic;public class Shape{
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    // 虛方法
    public virtual void Draw()
    {
        Console.WriteLine("執(zhí)行基類的畫圖任務(wù)");
    }}class Circle : Shape{
    public override void Draw()
    {
        Console.WriteLine("畫一個圓形");
        base.Draw();
    }}class Rectangle : Shape{
    public override void Draw()
    {
        Console.WriteLine("畫一個長方形");
        base.Draw();
    }}class Triangle : Shape{
    public override void Draw()
    {
        Console.WriteLine("畫一個三角形");
        base.Draw();
    }}class Program{
    static void Main(string[] args)
    {
        // 創(chuàng)建一個 List<Shape> 對象,并向該對象添加 Circle,、Triangle 和 Rectangle
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // 使用 foreach 循環(huán)對該列表的派生類進行循環(huán)訪問,,并對其中的每個 Shape 對象調(diào)用 Draw 方法
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("按下任意鍵退出。");
        Console.ReadKey();
    }}

當上面的代碼被編譯和執(zhí)行時,,它會產(chǎn)生下列結(jié)果:

  • 畫一個長方形

  • 執(zhí)行基類的畫圖任務(wù)

  • 畫一個三角形

  • 執(zhí)行基類的畫圖任務(wù)

  • 畫一個圓形

  • 執(zhí)行基類的畫圖任務(wù)

  • 按下任意鍵退出,。

下面的程序演示通過虛方法 area() 來計算不同形狀圖像的面積:

實例using System;namespace PolymorphismApplication{
   class Shape
   {
      protected int width, height;
      public Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      public virtual int area()
      {
         Console.WriteLine("父類的面積:");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): base(a, b)
      {

      }
      public override int area ()
      {
         Console.WriteLine("Rectangle 類的面積:");
         return (width * height);
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): base(a, b)
      {
     
      }
      public override int area()
      {
         Console.WriteLine("Triangle 類的面積:");
         return (width * height / 2);
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("面積: {0}", a);
      }
   }  
   class Tester
   {
     
      static void Main(string[] args)
      {
         Caller c = new Caller();
         Rectangle r = new Rectangle(10, 7);
         Triangle t = new Triangle(10, 5);
         c.CallArea(r);
         c.CallArea(t);
         Console.ReadKey();
      }
   }}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

Rectangle 類的面積:
面積:70
Triangle 類的面積:
面積:25


總結(jié)??

本篇文章介紹了C#中一些基礎(chǔ)知識,,是接著上一篇博客寫的
主要介紹了C#中的方法,、封裝繼承,、多態(tài)

可能有些地方寫的不是很全,,大概就是這樣啦。有空會繼續(xù)更新

傳送門

上 一 篇 \color{00ff90}{上一篇 } ?? 學(xué)會編程入門必備 C# 最基礎(chǔ)知識介紹(四)——數(shù)組、字符串,、結(jié)構(gòu)體,、枚舉、類
下 一 篇 \color{00ff90}{下一篇} ?? 學(xué)會編程入門必備 C# 最基礎(chǔ)知識介紹(六)——接口,、命名空間,、預(yù)處理指令、正則表達式,、異常處理,、文件的輸入與輸出

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多