C#學習基礎------域和屬性

域和屬性

域表示與對你或類相關聯的變量,聲明格式如下:
attributes  field-modifiers  type  variable-declarators;
域的修飾符field-modifiers可以是:
new
public
protected
internal
private
static
readonly
實際上,域相當於c++中的類的簡單成員變量,在下面的代碼中,類a包含了三個域:公有的x和

y,以及私有的z.
class a
{
  public int x;
  public string y;
  private float z;
}

靜態域和非靜態域
靜態域的聲明是使用static修飾符,其它的域都是非靜態域,靜態域和非靜態域分別屬於C#

中靜態變量和非靜態變量.
若將一個域說明為靜態的,無論建立多少個該類的實例,內存中只存在一個靜態數據的拷貝.

當這個類的第一個實例建立時,域被初始化.以後再進行類的實例化時,不再對其進行初始化

,所有屬於這個類的實例共享一個副本.
與之相反,非靜態域在類的每次實例化時,每個實例都擁有一份單獨的拷貝.
下面的例子清楚的反映了二者之間的區別.
using System;
public class Count
{
    static int count;
    int number;
    public Count()
    {
        count = count + 1;
        number = count;
    }
    public void show()
    {
        Console.WriteLine("object{0}:Number={1},Count={2}",number, number,

count);
    }
}
class test
{
    public static void Main()
    {
        Count a = new Count();
        a.show();
        Console.WriteLine();
        Count b = new Count();
        a.show();
        b.show();
        Console.WriteLine();
        Count c = new Count();
        a.show();
        b.show();
        c.show();
    }
}
程序運行結果:
object1:Number=1,Count=1

object1:Number=1,Count=2
object2:Number=2,Count=2

object1:Number=1,Count=3
object2:Number=2,Count=3
object3:Number=3,Count=3

上例的例子中,類Count中域count被聲明為靜態,為所有類的實例所共享.類每進行一次實例

化,它的值就加1,這個操作就在構造函數中實現,因為可以用於對系統中類的實例數進行計

數.
域number用來存放當前實例的編號.當被實例化時,在構造函數中就對編號進行賦值,從而可

以看出實例化的順序.
方法show()用來在屏幕上打印出當前類的實例數,還有類的各個實例的編號.
從上面的例子中可以看,出無論何時,類的所有實例的count值都是相同的,說明它們共享一

個數據,count域只有一個副本.而每個實例的標號都是不同的,一旦實例化,標號就不再變化

了.

只讀域
域的聲明中如果加上了readonly修飾符,表明該域為只讀域.對於只讀域我們只能在域的定

議中和它所屬類的構造函數中進行修改,在其它情況下,域是"只讀"的.
public class A
{
  public static readonly double PI=3.14159;
  public static readonly Color White=new Color(255,255,255);
  public static readonly int kByte=1024;
}
這樣,在程序中我們就可以直接使用PI來指代圓周率,white來表示白色...
那麼使用static readonly與使用const有什麼區別?簡單地說,const型表達式的值在編譯時

形成而static readonly表達式的值直到程序運行時才形成.看下面這個列子.
using System;
namespace Program1
{
  public class A
  {
    public static readonly int x=1;
  }
}
namespace Program2
{
  class Test
  {
    static void Main()
    {
      Console.WriteLine(Program1.A.x);
    }
  }
}
假定名字空間Program1&Program2表示兩個分別獨立編譯的程序.在這里域x為靜態只讀的,

它的值由在編譯時形成的,所以無認是否改變Program1中x的值,只要不重新編譯

Program2,Program2的輸出就不會發生變化.如果Program2已經安裝在用戶的系統上,對

Program1的升級不會影到舊的Program2的使用.這种技術有利於進行版本控制.

域的初始化
對靜態變量,非靜態的對像變量和數組元素,這些變自動初始化為體身的默認值.對於所有引用類型的變量,默認值為null.所有值類型的變量見下表:
 

對於struct類型的變量,默認的初始化將對構成該結構的每一個值類型初始化為上表中的默

認值,對構成其的每一個引用類型初始化為null.
如果在類中,沒有顯式地對域進行初始化,系統將賦予其一個默認值.域的默認初始化分為兩

种情況:對於靜態域,類在裝載時對其進行初始化;對於非靜態域,在類的實例創建時進行初

始化.在默認的初始化之前,域的值是不可預測的.
以下的代碼是合法的:
class Test
{
  static int a=b+1;
  static int b=a+1;
}
實際上等價於:a=1,b=2
而下面的代碼則是非法的:
class A
{
  int x=1;
  int y=x+1;
}
因為非靜太變量x在類A實例化以前並沒有初始化,代碼y=x+1無法得到的x的值.

屬性
屬性是對現實世界中實體特征的抽像,它提供了對類或是對像性的訪問.類的屬性所描述的

是狀態信息,在類的某個實例中屬性的值表示該對像的狀態值.
C#中的屬性更充分地體現了對像的的封裝性;不直接操作類的數據內容,而是通過訪問器進

行訪問.它借助於get和set對屬性的值進行讀寫,這在C++中是需要程序員手工完成的一項工

作.
屬性采用如下方式進行聲明:
attributes  property-modifiers  type  member-name  {accessor-declarations}

屬性的修飾符property-modifiers有:
new
public
protected
internal
private
static
virtual
sealed
override
abstract
以上修飾符中,static,virtual,override和abstract修飾符不能同時使用.

訪問屬性的值
在屬性的訪問聲明中,對屬性的值的讀操作用get關鍵字標出,對屬性的值的寫操作用set關

鍵字標出.下面是一個例子
using System;
public class File
{
  private string s_filename;
  public string Filename
  {
    get{return s_filename;}
    set
    {
      if(s_filename!=value)
      {
        s_filename=value;
      }
    }
  }
}
public class Test
{
  public static void Main()
  {
    File f=new File();
    f.Filename="myfile.txt";
    string s=f.Filename;
    Console.WriteLine("Filename:{0}",s);
  }
}
程序運行結果:
Filename:myfile.txt
在屬性的訪問聲明中:
只有set訪問器,表明屬性的值只能進行設置而不能讀出.
只有get訪問器,表明屬性的值是只讀的,不能改寫.
同時有set訪問器和get訪問器,表明屬性的值的讀寫都是允許的.
除了使用abstract修飾符的抽像屬性,每個訪問器的執行體只有分號";",其它所有屬性的get訪問器都通過return來讀取屬性的值,set訪問器都通過value來設置屬性的值.
舉個例子,旅館對信宿人員進行登記,要記錄的信息有:客人姓名,性別,所住的房間號,已住宿天數.這里,客人的姓名和性別一經確定就不能再更改了,用戶可以要求改變房間,住宿的天數當然也是不斷變化的.我們在類的構造函數中對客人的姓名和性別進行初始化,在四個屬性中,客人的姓名和性別是只讀的,故只有get訪問器;房間號和住宿天數允許改變,同時有set訪問器和get訪問器.
using System;
public class Customer
{
  public enum sex
  {
    man,
    woman,
  };
  private string s_name;
  Public string Name
  {
    get{return s_name;}
  }
  private sex m_sex;
  public sex Sex
  {
    get{return m_sex;}
  }
  private string s_no;
  public string No
  {
    get{return s_no;}
    set
    {
      if(s_no!=value)
      {
        s_no=value;
      }
    }
  }
  private int i_day;
  public int Day
  {
    get{return i_day;}
    set
    {
      if(i_day!=value)
      {
        i_day=value;
      }
    }
  }
  public void Customer(string name,sex sex,string no,int day)
  {
    s_name=name;
    m_sex=sex;
    s_no=no;
    i_day=day;
  }
}

posted @ 2007-11-01 10:37  Athrun  阅读(298)  评论(0编辑  收藏  举报