sealed關鍵字
如果我們将類标記為sealed,編譯器将不會允許我們從這個類型派生。(c#結構總是隐式密封的。是以,我們永遠不可以從結構繼承結構,從類繼承結構或從結構繼承類。結構隻能用于模組化獨立的、使用者定義的資料類型。如果希望是is-a關系,就必須使用類。)
使用base關鍵字控制基類的建立
protected關鍵字
派生類型不再需要使用公共方法或屬性來間接通路資料了。當然,可能的壞處在于:如果派生類型有權直接通路其父類内部資料,有可能會偶爾繞過公共屬性内設定的既有業務規則。當定義受保護成員時,也就建立了一種父類和子類之間的信任級别,編譯器不會捕獲任何違背類型業務規則的異常。
包含/委托程式設計
class benefitpackage
{
public double computepaydeduction()
{ return 125.0; }
}
partial class employee
protected benefitpackage empbenefits=new benefitpackage();
public double getbenefitcost()
{ return empbenefits.computepaydeduction(); }
public benefitpackage benefits
{ get { return empbenefits; }
set { empbenefits=value; }
}
.......
嵌套類型
public class outerclass
//公共嵌套類型可以被任何人使用
public class publicinnerclass { }
//私有嵌套類型隻可以被包含類的成員使用
public class privateinnerclass { }
嵌套類型的特征:
通過嵌套類型可以完全控制内部類型的通路級别,也就是可以聲明為私有的(回憶一下,非嵌套類不能使用private關鍵字來聲明)。
由于嵌套類型是包含類的成員,是以它可以通路包含類的私有成員。
通常,嵌套類型隻用做外部類的輔助方法,而不是外部世界所準備的。
//employee嵌套benefitpackage
public partial class employee
// benefitpackage嵌套benefitpackagelevel
public class benefitpackage
{
public enum benefitpackagelevel
{ standard,gold,platinum }
}
public double computepaydeduction()
{ return 125.0 }
在這種嵌套關系裡需要注意如何使用枚舉:
employee.benefitpackage.benefitpackagelevel mybenefitlevel=employee.benefitpackage.benefitpackagelevel.platinum;
virtual和override關鍵字
多态為子類提供了一種方式,使其可以定義為由其基類定義的方法,這種過程叫做方法重寫。
poblic virtual void givebonus(float amount)
{ pay+=amount ; }
......
用virtual關鍵字标記的方法成為虛方法。
如果子類希望改變虛方法的實作細節,就必須使用override關鍵字。
class salesperson:employee
{ .......
//銷售人員的獎金受銷量的影響
public override void givebonus(float amount)
{
int salesbonus=0;
if(numberofsales>=0&&numberofsales<=100)
salesbonus=10;
else
{ if(numberofsales>=101&&numberofsales<=200)
salesbonus=15;
else
salesbonus=20;
}
base.givebonus(amount*salesbonus);
}
class manager:employee
public override void givebonus(float amout)
{ base.givebonus(amount);
random r=new random();
numberofoptions+=r.next(500);
密封虛成員
{ ........
public override sealed void givebonus(float amount)
{ ....... }
sealed class ptsalesperson:salesperson
public ptsalesperson(string fullname,int age,int empid,float currpay,string ssn,int numbofsales)
:base(fullname,age,empid,currpay,ssn,numbofsales)
{ }
// 編譯器錯誤!不能在ptsalesperson類中重寫這個方法,因為它是被密封的
{ }
抽象類
由于很多基類都是比較模糊的屍體,好的設計師會防止在代碼中直接建立新的employee對象。
abstract partial class employee
{ ........ }
建構多态接口
成員投影
基類/派生類的轉換規則
as關鍵字
//我們不能強制轉換frank為hexagon,但編譯沒問題
hexagon hex=(hexagon)frank;
//使用“as”來測試相容性
hexagon hex2=frank as hexagon;
if(hex2==null)
console.writeline("sorry,frank is not a hexagon...");
is關鍵字
除了is關鍵字,c#語言還提供了is關鍵字來測試兩個項是否相容。然而,和as關鍵字不同的是,如果類型不相容,is關鍵字就傳回false而不是null引用。
超級父類:system.object
system.object的核心成員
equals() 預設情況下,如果被比較的項指向記憶體中同一個項,則方法會傳回true。是以,equals()用于比較對象引用,而不是對象的狀态。一般情況下,這個方法被重寫為:如果被比較的對象有相同的内部狀态值(也就是基于值的語義),則傳回true。要知道,如果重寫equals(),則還需要重寫gethashcode(),因為這些方法在内部用于hashtable類型從容器讀取子對象。valuetype類為所有結構重寫了該方法,它們進行的比較是基于值的。
finalize() 這個方法(在重寫後)在對象銷毀之前被調用來釋放所配置設定的資源。
gethashcode() 這個方法傳回int來辨別指定的對象執行個體。
tostring() 這個方法是用<namespace>,<type name>格式(叫做完全限定名)傳回對象的字元串表示。這個方法可以被子類重寫來傳回名稱/值對的辨別字元串以表示對象的内部狀态,而不是它的完全限定名。
gettype() 這個方法傳回type對象,它完整描述目前指向的對象。簡而言之,這是所有對象都可用的運作時類型辨別方法。
memberwiseclone() 這個方法的作用是逐個成員地傳回目前對象的副本,通常用于克隆對象。