繼承密封類
子類的初始化順序
多型所有類的父類systemobject
c#中的物件導向程式設計是指3個基本特徵:封裝、繼承、多型。
當類的內部資料沒有被封裝時,若把字段定義為公共字段,則外部物件可以對內部資料進行任意的操作,很可能導致不當的操作結果。例如:
public
class person
class program
}
以上**中,雖然程式可以正常執行,但是邏輯上有問題,因為人的年齡不可能為負。
這就是外部物件對類內部資料進行任意操作的產生的不當結果。為了避免這種情況,可以將類進行封裝。
public
class person
setage = value;}}
public
string name
set}
}class program
}
以上**中,person.age設定為乙個不合理的數(小於0,大於100)時,執行時程式會中斷,並丟擲argumentoutofrangeexception。
在c#中,乙個類可以繼承另乙個已有類(密封的除外),被繼承的類稱為基類(或父類),繼承的類稱為派生類(或子類),子類將獲得基類除建構函式和析構函式以外的所有成員。此外,靜態類是密封類,不能被繼承。
簡單來說,乙個類定義了一些方法、屬性等,若另乙個類也要定義同樣的方法、屬性等,可以直接通過繼承的方式來獲得基類的所有方法、屬性等,避免了**重複。並且同時,子類可以定義另外一些自有的方法、屬性等。這就好比男人女人都先擁有人的屬性,然後還可以定義自有的屬性。
在c#中,子類僅支援派生於乙個基類,也就是乙個子類僅可有乙個父類。但乙個父類可以有多個子類。這些子類都繼承父類相同的成員。c#中繼承的方法為:
//定義乙個基類
public
class father
//子類繼承父類
public
class childa : father
public
class childb : father
需要注意的是,子類並不能對父類的私有成員進行直接訪問,它只可對保護成員和公有成員進行訪問。但是子類會繼承基類的私有成員,子類可以通過呼叫公有或保護方法間接的對自有成員進行訪問。
上面說到,乙個類可以繼承另乙個除密封類以外的類。所以,若不想被繼承,則可以使用sealed關鍵字將其定義為密封類。方法為:
public
sealed
class sealedclass
若有類要繼承該密封類時,編譯器會報錯。
上面說到,子類不會繼承基類的建構函式和析構函式。但是當子類進行初始化時,任然會呼叫基類的建構函式。
初始化順序為:
①初始化子類的例項字段;
②呼叫基類的建構函式,若沒有指明基類,則呼叫system.object的建構函式;
③呼叫子類的建構函式;
例如:
class program
}//建立乙個父類father
public
class father
//呼叫基類建構函式
public
father()
}//建立乙個子類child
public
class child : father
//呼叫子類建構函式
public
child()
}
執行以上**,結果為:
需要注意,執行結果顯示,初始化子類例項時,先執行了基類的建構函式,再執行了子類的建構函式,最後執行了子類的方法。並未執行基類的方法,且子類執行順序並不是按**順序先執行方法再執行建構函式。因此可見總是要並先要執行父類的建構函式,第二再執行子類的建構函式。
簡單來說,如果乙個子類繼承了乙個基類,則獲得了基類中的某些行為(如方法、屬性等),但是如果子類想改變繼承的方法,就需要覆寫基類的方法,這種技術就稱為多型。
基類成員宣告為virtual(稱為虛方法)時,子類可以重寫,如果想改變虛方法的實現行為,要使用override關鍵字。例如:
class program
}public
class father
}public
class son : father
}public
class daughter : father
}
執行以上**,結果為:
由此可見,子類繼承了基類虛方法後對虛方法進行了覆寫,在兒子類中覆寫時呼叫了基類方法,因此執行結果仍然有基類方法。女兒類中覆寫時未呼叫基類方法,執行結果則無基類方法。
可見,多型的精髓是相同型別的物件呼叫相同的方法卻表現了不同的行為。
用1實現多型時會存在乙個問題,即基類可以通過new操作符建立基類的例項。可有的情況下,基類是乙個抽象概念(如:人、動物、天氣),我們希望避免建立這種抽象的例項。此時可用abstract關鍵字來防止在**種直接建立這樣的例項,然後仍然可用1實現多型。例如:
public
abstract
class wether
}public
class rain : wether
}public
class sun : wether
}class program
}
執行以上**,結果為:
若將main中的建立基類例項的注釋取消,則會報錯:
前面講到可以用sealed關鍵字來密封類,同理,可以用sealed關鍵字來密封子類方法防止子類被重寫。例如:
public
abstract
class parent
}public
class son : parent
}
以上**的類son無法被覆寫,若新增以下**:
public
class grandson : son
}
則會顯示錯誤資訊:無法對密封成員進行複寫
。
有的情況下,子類需要定義與基類相同名字的成員,此時可以用new關鍵字將基類成員隱藏起來。若不使用new關鍵字,則會報錯。例如:
public
class father
}public
class son : father
}
如果此時仍然想要訪問基類的成員,可使用強制型別轉換,把子類強制轉換成基類型別,從而訪問隱藏的基類成員。例如:
class
program
}
以上**,結果為:
c#中,所有的類都派生自system.object類。如果類沒有指定任何的基類,則編譯器就自動吧object當作它的基類。
詳細資訊請參考:object類(system)
C 中的物件導向程式設計
所有的物件導向語言都具有3個基本特徵,c 也是不例外的。1 封裝 封裝指的是把類內部的資料隱藏起來,不讓物件例項直接對其操作。在c 中,封裝可以通過public private protected和internal等關鍵字來體現。c 對保護內部資料狀態提供了一種方式,叫做屬性機制。public cl...
c 物件導向程式設計 物件導向
什麼是物件導向 是對現實世界理解和抽象的方法。物件導向程式設計的特點 易維護,易擴充套件,靈活性好,重用 類 對事物的抽象定義,即事物具有的共同特徵和行為。物件 即對類進行例項 類是抽象的,物件是具體的 類的定義 語法 訪問修飾符 class 類名類的成員 包括字段,屬性,方法,常量,事件和索引器等...
程式語言 C 中的物件導向
最近終於學到了c 了,真的很高興啊!畢竟是要從面向過程跳到物件導向的時候了,雖然以前學過c 但是還是覺得自己的物件導向的思想很不做,希望通過對c 的學習能夠打下乙個堅實的基礎,然後在這個基礎上再學習其他新的物件導向語言就不是事兒了。一 介紹篇 c 是一種安全的 穩定的 簡單的 優雅的,由c和c 衍生...