1. 程式人生 > >C#類中欄位封裝為屬性

C#類中欄位封裝為屬性

本文描述內容轉載 https://zhidao.baidu.com/question/1174413218458798139.html 感謝 冥冥有你PD 的解答!!!

問題思索1

類成員包括變數和方法。如果希望其他類能夠訪問成員變數的值,就必須定義成公有的,而將變數設為公有public,那這個成員變數的就可以被任意訪問(包括修改,讀取),這樣不利於資料安全。那怎麼辦呢?

解決方案

1.C#通過屬性特性讀取和寫入欄位(成員變數),而不直接直接讀取和寫入,以此來提供對類中欄位的保護。

2.屬性可用於類內部封裝欄位。屬性是C#面向物件技術中封裝性的體現(注意:欄位就是類的成員變數,為配合屬性而這樣稱呼的)

屬性和欄位的區別

1.屬性是邏輯欄位;

2.屬性是欄位的擴充套件,源於欄位;

3.屬性並不佔用實際的記憶體,欄位佔記憶體位置及空間。

4.屬性可以被其它類訪問,而類中大部分欄位不能直接訪問。

5.屬性可以對接收的資料範圍作限定,而欄位不能(也就是增加了資料的安全性)最直接的說:屬性是被“外部使用”,欄位是被“內部使用”。

問題思索2

要屬性這種華而不實的東西做什麼?為什麼不直接放一個public欄位?

class Card
{

  public string Name;    //而非要做一個private欄位+public屬性?
}

 

#region ClassStart***************************************************

class Card{

  private string name;
  public string Name{

  get { return this.name;}

  public string sex;

}

  //宣告一個類去使用User類

  class Property{

    static void Main(){

    //例項化一個張三User物件

    User zs = new User();
    //對其賦值

    zs.name = "張三";

    zs.sex = "男";

    Console.WriteLine("姓名:" + zs.name + "性別:" +zs.sex);

  }
}

#Endregion ClassEnd***************************************************

 

通過編譯執行,這段程式碼正常執行,這個程式乍看一下感覺沒有什麼問題。但是仔細分析,就會發現:所有欄位都是公有的,不利於欄位的保護,只要例項化了這個類,都可以修改其中的值。

如果性別輸入了男女之外的字元,系統是不會識別的。比如把zs.sex = "男";改成zs.sex = "牛";

執行程式碼結果肯定張三的性別成牛了...這個時候就不合邏輯了。現在大家可以明顯的感覺到User類的封裝非常不合理,存在著非常大的缺陷,那麼該如何修改呢?這個時候大家馬上會想到是不是可以專門宣告一個方法給性別賦值呢,

 

#region ClassStart***************************************************

using System;

class User

{

  public string name;
  public string sex;
  //SetSex方法

  public void SetSex(string values)

  {if (values == "男" || values =="女") {
    sex =values;}

  else{

    Console.WriteLine("性別只能為“男”或“女”"); }

  }

}

class Property

{

  static void Main() {

  User zs = new User();
  zs.name = "張三";

  //直接呼叫SetSex賦值

  zs.SetSex("牛");

   Console.WriteLine("姓名:" + zs.name + "性別:" +zs.sex);

  }
}

#Endregion ClassEnd***************************************************

SetSex這個方法乍一看還可以,但是不要忘記name和sex欄位還是public屬性,我們依然可以直接去呼叫它,或者說去修改它,一樣可以把sex設為“牛”。

給類的欄位設定為public意味著破壞了類的封裝,這樣會存在潛在的危險。所以要設為private,這個時候就分別宣告方法去讀取和設定這2個欄位。

 

 
#region ClassStart***************************************************

using System;

class User{

  //設為私有的

  private string name;
  private string sex;
  //設定

  public void SetName(string values){

    name = values;

  }

  //讀取

  public string GetName(){

    return name;

  }

  public void SetSex(string values)

  {if (values == "男" || values =="女") {
    sex =values;

  }

  else{

    Console.WriteLine("性別只能為“男”或“女”");

   }

}

  public string GetSex(){

    return sex;

  }

}

class Property{

  static void Main(){

    User zs = new User();

    zs.SetName("張三");

    zs.SetSex("牛");

    Console.WriteLine("姓名:" + zs.GetName() +"性別:" +zs.GetSex());

  }
}

#Endregion ClassEnd***************************************************

現在這個類的設計就比較合理了,我們看name和sex它們是private欄位,也就是說在類的外部是不能訪問的,這樣呢就保證了它的安全性。

當用戶想給性別欄位新增非法欄位的時候,SetSex方法內會對這個新增的值進行判斷,如果不為男或女,值就不會被新增。

通過方法雖然解決了上面的問題,但是每建立一個物件,輸入欄位值時就必須呼叫上面方法。

如果不知道,就無法呼叫。關鍵是不夠簡便。為了提高資料安全性,並且有效解決上面的問題。

C#推出了屬性。可以建立屬性,將欄位和屬性封裝在一起。通過屬性可以像訪問欄位一樣訪問資料成員。

實現資料的封裝,避免使用非法資料賦值,保證資料完整性,同時類內部發生修改時,避免整個程式的修改。