我們定義了YSchool,YTeacher類,實例化對象時:
[csharp]
YSchool shool1 = new YSchool();
shool1.ID = 1;
shool1.Name = "清華附中";
YSchool school2 = new YSchool();
school2.ID = 2;
school2.Name = "北師大附中";
YSchool shool1 = new YSchool();
shool1.ID = 1;
shool1.Name = "清華附中";
YSchool school2 = new YSchool();
school2.ID = 2;
school2.Name = "北師大附中";
這樣寫對不對呢,其實在邏輯上是不正確的,因為實例化對象時,它的屬性應該是和實例化一起就有的,而不是後來再加屬性。在程序中表現就是,屬性要有初值。
所以,在類中就要有這樣一個方法,無返回類型,方法名和類名相同,有參數類表或者沒有參數列表。它就是構造方法,俗稱“構造器”或“構造函數”。一個類中可以有一個或多個構造函數,當然有時你沒寫構造函數,這並不代表這個類就沒有構造函數,它依然有一個默認的構造函數的。如果使多個構造函數的話,它們各自的參數列表必須不同。
下面以YSchool為例完善這個類。
[csharp]
/// <summary>
/// YSchool類的id和name是它的固有屬性,它的值應該是確定的。
/// 實例化的同時對屬性賦初值,用到構造函數。
/// </summary>
public class YSchool
{
private int id = 0;
private string name = string.Empty;
public int ID
{
get
{
return this.id;
}
}
public string Name
{
get
{
return name;
}
}
/// <summary>
/// 沒有參數的構造器稱之為“默認構造器”;如果沒有寫一個構造器,那麼
///系統也會提供一個默認的構造器,所以說類至少有一個構造器;
///當然,如果系統提供的默認構造函數,則屬性初值為聲明時賦的初值,如果聲明
///未賦初值,則是“類型默認值”,比如0或者null。
/// </summary>
public YSchool()
{
this.id = 0;
this.name = @"清華附中";
}
/// <summary>
/// 帶有參數列表的構造函數,
/// 屬性的值就是傳入的列表的值。
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public YSchool(int id, string name)
{
this.id = id;
this.name = name;
}
public YSchool(int id)
{
this.id = id;
this.name = @"陝科大附中";
}
}
/// <summary>
/// YSchool類的id和name是它的固有屬性,它的值應該是確定的。
/// 實例化的同時對屬性賦初值,用到構造函數。
/// </summary>
public class YSchool
{
private int id = 0;
private string name = string.Empty;
public int ID
{
get
{
return this.id;
}
}
public string Name
{
get
{
return name;
}
}
/// <summary>
/// 沒有參數的構造器稱之為“默認構造器”;如果沒有寫一個構造器,那麼
///系統也會提供一個默認的構造器,所以說類至少有一個構造器;
///當然,如果系統提供的默認構造函數,則屬性初值為聲明時賦的初值,如果聲明
///未賦初值,則是“類型默認值”,比如0或者null。
/// </summary>
public YSchool()
{
this.id = 0;
this.name = @"清華附中";
}
/// <summary>
/// 帶有參數列表的構造函數,
/// 屬性的值就是傳入的列表的值。
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public YSchool(int id, string name)
{
this.id = id;
this.name = name;
}
public YSchool(int id)
{
this.id = id;
this.name = @"陝科大附中";
}
}[csharp]
class Program
{
static void Main(string[] args)
{
YSchool shool1 = new YSchool();
YSchool school2 = new YSchool(1, @"西工大附中");
YSchool school3 = new YSchool(2);
Console.ReadKey();
}
}
class Program
{
static void Main(string[] args)
{
YSchool shool1 = new YSchool();
YSchool school2 = new YSchool(1, @"西工大附中");
YSchool school3 = new YSchool(2);
Console.ReadKey();
}
}
上面還修改了id和name的get/set屬性,都改為只有get,因為這些屬性值都是固有屬性,實例化之後再賦值也就不符合邏輯了。也就是這些屬性是只讀的。
代碼中提到了默認值,這裡簡單說一下。在聲明字段的時候,可以用賦值運算符“=”給字段直接加一個值,比如
[csharp]
string name = string.Empty;
string name = string.Empty;
這個不是給變量賦值,默認值只是一種形式,真正給變量賦值還是在構造函數中。一般規范的代碼都要求聲明變量時要賦初值的。如果生命時沒有賦值的字段,都會由編譯器增加一句賦值代碼,將該字段賦值為設定的默認值。其實,無論我們是否給字段增加了默認值,字段都具備默認值的,只不過如果我們沒有人為增加默認值,字段的默認值將是0或null。
這裡還有一點要注意,前面提到過系統默認的構造函數,但是當定義了構造函數後,系統默認構造函數就不存在了。因此如果某些情況下,既要用到默認構造函數和帶參數的構造函數,就要手動定義默認構造函數了。比如,
[csharp]
public YSchool()
{
}
public YSchool()
{
}
或者
[csharp]
public YSchool()
{
this.id = 0;
this.name = @"尚進";
}
public YSchool()
{
this.id = 0;
this.name = @"尚進";
}
綜上所述實例化類的規范表達式應該是:類名 實例名 = new 類名(構造函數參數列表);
作者:yysyangyangyangshan