想繼承+多態性
下面是一些代碼,我會照顧做出點.. 。
public abstract class WeirdPerson() {
public virtual void DoThis() {
// base/default implementation as desired
}
public virtual void DoThat() { // ditto }
public abstract void GoWildAndCrazy;
}
public class WeirdChild : WeirdPerson {
public override void DoThis() { // weird child behavior}
// etc.
}
public class WeirdDad : WeirdPerson {
// override and add methods as needed.
}
public class Version_1
{
public string Name { get; protected set; }
public int Age { get; protected set; }
public WeirdPerson WeirdFamilyMember { get; protected set; }
public MysteriousDad Mysterious { get; protected set; }
public Version_1 (WeirdChild child, string name, int age, MysteriousDad Dad) {
}
}
public class Version_2 : Version_1 {
public Version_2 (WeirdDad dad, string name, int age, MysteriousDad grandfather) : base (dad, name, age, grandfather) {}
}
WeirdPerson
- 爲所有子類型定義基本內容的更一般概念。
- 子類型將得到「固定」之類的東西
Name
- 繼承
- 子類型可以
override
默認行爲(方法) - 多態性 現在
- 我們沒有滑稽的東西:
public class WeirdDad : WeirdChild
- 構造
Version_1
,Version_2
構造函數強制客戶端提供正確的WeirdPerson
子類型。
- 客戶必須給我們所有必需的東西。
- 我們可以驗證/交叉驗證傳入參數。
- 我們不需要任何討厭的
interface
abstract
類允許我們有默認的行爲(方法)和默認狀態(性質)的任何類的
public
方法和屬性是一般意義上的接口。我們不需要(C#關鍵字)interface
爲了遵循原理代碼接口不執行
abstract
方法強制子類實現。只是。喜歡。一個。interface
。
new
- 警告。方法隱藏在當時斷開了繼承鏈。如果我們從這個類繼承,我們不會繼承原始基類的方法實現。
- 里氏是幸福的。
附加重構
充分利用Version
層次結構平行的WeirdPerson
層次結構
假設這適合你的設計。我想,一年之後,你會很高興你做到了。
public abstract class Version_X {
// all the original properties here.
// virtual and abstract methods as needed
// LOOK! standard-issue constructor!
protected Version_X (WeirdPerson person, ...) { // common validation, etc. }
}
public class Version_1 : Version_X {
public Version_1(WeirdChild child, ...) : base (child, ...) {}
}
public class Version_2 : Version_X {
public Version_2 (WeirdDad dad, ...) {}
}
編輯 - 通過comment discussion with DVK
最少知識原理的啓發說,客戶不應該知道內部細節使用類。需要知道如何撰寫正確的Version
和Weird
是一種違規行爲,可以爭辯。
讓我們假設一個默認的構造函數,爲Visitor
比方說,有必要在整體設計別處。允許這意味着客戶可以控制Version
/Weird
組合。
抽象 - 鬆散耦合 - 在abstract
類。具體類必須正確組成,所以「強耦合」在創建具體對象(顯式類型構造函數參數)中是固有的,但底層鬆耦合允許具有所需的靈活性。
public enum WeirdFamily { Child, Dad, Mother, TheThing }
public static class AdamsFamilyFactory() {
public static Version_X Create (WeirdFamily familyMember) {
switch (familyMember) {
case Dad:
return BuildAdamsDad();
// . . .
}
}
}
public static class MunstersFactory() { // Munsters implementation }
// client code
List<Version_X> AdamsFamily = new List<Version_X>();
Version_X Pugsly = AdamsFamilyFactory.Create(WeirdFamily.Child);
AdamsFamily.Add(Pugsly);
List<Version_X> Munsters= new List<Version_X>();
Version_X Eddie= MunstersFactory.Create(WeirdFamily.Child);
Munsters.Add(Eddie);
DoTheMonsterMash(Munsters);
DoTheMonsterMash(AdamsFamily);
public void DoTheMonsterMash(List<Version_X> someWeirdFamily {
foreach (var member in someWeirdFamily)
member.GoWildAndCrazy();
}
爲什麼你不抽象奇怪和神祕的爸爸屬性返回版本1可能的最抽象的基礎?您打算使用v2進行的更改會破壞客戶端代碼。孩子和爸爸都是「人」,因此,讓它返回人,使其虛擬,然後你可以在沒有制動客戶的情況下重寫你的怪異吸氣劑,因爲怪異也是一個人 –
你正在尋找的東西叫做「隱藏」,你當你編譯上面的代碼時,可能會得到編譯器的警告,但是你通過聲明屬性「new」來明確隱藏,即:'public new WeirdChild Weird {get;組; }'但是請注意,當使用聲明爲'Version_1'的'Version_2'對象時,這可能會引起混淆,如'Version_1 child = new Version_2();','child.Wierd'將在基類上操作,而不是派生一。 –
我很抱歉,但您的問題並不清楚。您不希望從'Version_2'對象的實例的基類中看到屬性'Weird',並且想隱藏它? –