1. 程式人生 > >13.C# 定義類成員

13.C# 定義類成員

sin 工作 標準 其他 abstract ole 名稱 str 擁有

1.定義字段

class MyClass
{
   public int MyInt;  
}

字段可以用readonly修飾,表示該字段只能在構造函數中賦值,還可以用static表示該字段是靜態字段

class MyClass
{
    public int MyInt=17;//註意公共字段使用PascalCasing標準命名,即每個單詞首字母大寫
    private  int age=18; //私有變量用camelCasing標準命名,首字母小寫,之後每個單詞首字母大寫
    public int StaInt =13;    
}    

2.定義屬性

class MyClass
{
    private int myInt;
    public int MyInt{
        get{return myInt;}
        protected set { myInt=value;}//set訪問器只當前類和繼承該類的子類能訪問
}    }

屬性擁有兩個類似函數的塊,稱為訪問器,可以忽略其中一個訪問器來創建只讀或只寫屬性。訪問器可以擁有自己的訪問修飾符,但訪問性不能高於它所屬的屬性。屬性可以用abstract、virtual、override修飾,但不能用於字段。

C#提供了一種定義屬性的簡寫方式,可以不用定義私有字段,編譯器會自動添加一個用於存儲該屬性的字段,但我們不知道該字段叫什麽,無法直接對該字段進行修改。

public int MyInt { get; set; }

3.定義方法

    class MyClass
    {
        public void GetString()
        {
            Console.WriteLine("AAAA");
        }
    }

方法可以用可訪問修飾符public、protected、internal、private修飾,默認為private;非訪問修飾符virtual、override、abstract、sealed、extern、static修飾,extern表示方法定義放在其他地方

4.隱藏基類方法

當基類的方法不像預期的那樣工作時可以使用new關鍵字隱藏基類的方法,如

    class Program
    {
        static void Main(string[] args)
        {
            MyClass a = new MyClass();
            a.DoingSomething();//子類方法
            MyBaseClass b = a;
            b.DoingSomething();//基類方法
            Console.ReadLine();
        }
    }

    class MyBaseClass
    {
        public void DoingSomething()
        {
            Console.WriteLine("基類方法");
        }
    }

    class MyClass : MyBaseClass
    {
        public new void DoingSomething()
        {
            Console.WriteLine("子類方法");
        }
    }

隱藏基類方法時,使用子類對象調用訪問的是子類的方法,使用父類對象調用訪問的是父類的方法,註意隱藏和重寫的區別,重寫時不管用子類還是父類對象調用方法,都將訪問的是子類的方法(多態性),如下

    class Program
    {
        static void Main(string[] args)
        {
            MyClass a = new MyClass();
            a.DoingSomething();//子類方法
            MyBaseClass b = a;
            b.DoingSomething();//子類方法
            Console.ReadLine();
        }
    }

    class MyBaseClass
    {
        public virtual void DoingSomething()
        {
            Console.WriteLine("基類方法");
        }
    }

    class MyClass : MyBaseClass
    {
        public override  void DoingSomething()
        {
            Console.WriteLine("子類方法");
        }
    }

5.調用重寫或隱藏的基類方法

有時候可能是在父類方法的基礎上做修改,這樣在重寫方法時就需要調用父類的方法,可以使用base關鍵字調用重寫的父類方法

class MyBaseClass
    {
        public virtual string DoingSomething()
        {
            return "父類方法";
        }
    }

    class MyClass : MyBaseClass
    {
        public override string DoingSomething()
        {
            return base.DoingSomething()+ " 子類方法";
        }
    }

註:base代表的是父類的對象實例,所以不能在靜態方法中調用

6.this 關鍵字

this關鍵字代表當前類的對象實例,可以使用this關鍵字訪問當前對象的實例成員。和base一樣this不能用在靜態方法中

    class MyClass
    {
        public  void DoingSomething(object o)
        {
            this.WriteSomething(this);//用this調用成員方法,並把當前對象實例傳給該方法
        }

        public void WriteSomething(MyClass c)
        {
            Console.WriteLine(c.ToString());
        }
    }

7.接口的實現

    interface IMyInterface
    {
        void DoingSomething();
        void DoingSomethingElse();
    }

    class MyClass : IMyInterface
    {
        public void DoingSomething()
        { 
        }

        public void DoingSomethingElse()
        {
        }
    }

也可以在基類中實現接口成員,如

    interface IMyInterface
    {
        void DoingSomething();
        void DoingSomethingElse();
    }

    class MyBaseClass
    {
        public void DoingSomething()
        {
        }
    }

    class MyClass : MyBaseClass
    {
        public void DoingSomethingElse()
        {
        }
    }

父類中實現了方法DoingSomething,子類只要實現剩余的方法即可

以上兩種方法是隱式的實現接口,下面是顯示實現接口的方法

    interface IMyInterface
    {
        void DoingSomething();
        void DoingSomethingElse();
    }


    class MyClass : IMyInterface
    {
        void IMyInterface.DoingSomethingElse()
        {
        }

        void IMyInterface. DoingSomethingElse()
        {
        }
    }

隱式實現接口和顯式實現接口的區別在於:隱式實現接口需要用public修飾實現的成員,而顯式實現的成員不能有訪問修飾符修飾,並且需要用接口名.成員名限定實現的接口成員。

除了語法上的區別外,顯式實現的接口成員只能通過接口訪問,隱式實現的成員可以通過接口和類來訪問。即

顯式實現的接口成員只能用如下方式訪問

            IMyInterface b = new MyClass();
            b.DoingSomething();

隱藏實現的可以這兩種方式都可以

            MyClass a = new MyClass();
           
            a.DoingSomething();//子類方法

            IMyInterface b = new MyClass();
            b.DoingSomething();

8.嵌套類型的定義(內部類)

C#類內部不僅可以定義方法、變量等成員,也可以在類內部定義類,此時內部類不僅能使用public、internal關鍵字修飾,還可以使用private、protected修飾

public class MyClass
    {
        public class myNestedClass
        {
            public int nestedClassField;
        }

        public myNestedClass GetInternalClass()
        {
            return new myNestedClass();
        }
    }

如果內部類是public或者internal的就可以在MyClass類外部定義內部類的實例,但必須用限定名稱

 MyClass.myNestedClass n = new MyClass.myNestedClass();

9.部分類

C#可以使用部分類定義,把類的定義放在多個文件中。如把字段、屬性和構造函數放在一個文件,而把方法放在另一個文件。部分類定義對於用來隱藏窗口布局代碼非常有用

    public partial class MyClass
    {
        //類體
    }

應用於部分類的接口會應用於整個類,下面兩種方式是等價的

方式一:

    public partial class MyClass:IMyInterface1
    {
        //類體
    }

    public partial class MyClass:IMyInterface2
    {
        //類體
    }

方式2:

  public  class MyClass:IMyInterface1,IMyInterface2
    {
        //類體
    }

10.部分方法

可以在部分類中定義部分方法,在一個部分類中定義部分方法,但不包含方法體,在另一個部分類中包含實現代碼

    public partial class MyClass
    {
        partial void MyPartialMethod();
    }

    public partial class MyClass
    {
         partial void MyPartialMethod()
         {
            
         }
    }

部分方法可以是靜態的,但是部分方法總是private,且不能有返回值,它們使用的參數也不能是out類型。因為部分方法如果沒有方法體,編譯器會完全刪除該方法。如果方法有返回值,那麽該方法就可以作為表達式的一部分,如

int a =Func(a,b)

如果Func是部分方法且沒有方法體,那麽編譯器就不知道怎麽執行上一句代碼;同樣如果輸入參數是out類型,因為out類型的參數必須在方法體內賦值,如果沒有方法體就會有問題。

分部方法不能具有訪問修飾符或 virtual、abstract、override、new、sealed 或 extern 修飾符

13.C# 定義類成員