Re: [問題] 變數宣告在if結構裡

作者: StupidGaGa (笨嘎嘎)   2014-05-19 14:14:22
你這樣寫會讓其他人亂用繼承關係。
原PO的解答的確是要用多型,Abb大寫的沒錯。
但是「如何寫」是一回事,
你有用到DesignPattern的概念,寫出來的東西卻打了自己一巴掌。
====文字檔====
文字檔Father.txt
Father
My name is Darth Vader.
I am your Father!
文字檔Son.txt
Son
My name is Luke Skywalker.
No~~~~~~~~~!
====程式碼====
程式碼Family.cs
abstract public class Family
{
public string StrA { get; set; }
public string StrB { get; set; }
public Family(StreamReader reader)
{
this.StrA = reader.ReadLine();
this.StrB = reader.ReadLine();
}
public abstract void ShowStrA();
public abstract void ShowStrB();
}
程式碼Father.cs
public class Father : Family
{
public Father(StreamReader reader)
: base(reader)
{
}
public override void ShowStrA()
{
Console.WriteLine(this.StrA);
}
public override void ShowStrB()
{
Console.WriteLine(this.StrB);
}
}
程式碼Son.cs
public class Son : Family
{
public Son(StreamReader reader)
: base(reader)
{
}
public override void ShowStrA()
{
Console.WriteLine(this.StrA);
}
public override void ShowStrB()
{
Console.WriteLine(this.StrB);
}
}
程式碼FamilyFactory.cs
public class FamilyFactory
{
public static Family CreateFamily(string familyMember, StreamReader
reader)
{
if (familyMember == "Father")
{
return new Father(reader);
}
else if (familyMember == "Son")
{
return new Son(reader);
}
else
{
return null;
}
}
}
客戶端調用
StreamReader reader1 = new StreamReader("Father.txt");
StreamReader reader2 = new StreamReader("Son.txt");
string familyMember1 = reader1.ReadLine();
string familyMember2 = reader2.ReadLine();
Family family1 = FamilyFactory.CreateFamily(familyMember1, reader1);
Family family2 = FamilyFactory.CreateFamily(familyMember2, reader2);
family1.ShowStrA();
family2.ShowStrA();
family1.ShowStrB();
family2.ShowStrB();
結果
My name is Darth Vader.
My name is Luke Skywalker.
I am your Father!
No~~~~~~~~~!
Father類別或Son類別是不同的,
只有新手或不熟悉物件導向的人才會直接用Son來繼承Faher,
這兩個類別都應該抽像於Family類別,
這樣子寫才比較好維護也有彈性。
Abb大說的多型是這樣,
只不過我偷懶把strA跟strB的readline寫在建構式。
※ 引述《adrianc (123)》之銘言:
: 看完後整整十分鐘心神不寧無法繼續工作,決定趁吃飯前回一下。
: 由原PO回文中已知兩個類別是繼承關係。
: 依照原文推文中的Abb大建議,實作程式碼。
: // 以下程式碼依原程式內容
: // 預期檔案第一行可能讀到 "father" or "son" 之外的內容,且不須處理
: // 變數命名使用原程式命名方式
: private void button1_Click(object sender, EventArgs e)
: {
: System.IO.StreamReader file = new System.IO.StreamReader("file.txt");
: string str = file.ReadLine();
: ClassFather xxx = null;
: if (str == "father)
: {
: xxx = new ClassFather();
: }
: else if (str == "son")
: {
: xxx = new ClassSon();
: }
: if (xxx != null)
: {
: xxx.strA = file.ReadLine();
: xxx.strB = file.ReadLine();
: }
: }
:
作者: adrianc (123)   2014-05-19 14:48:00
你要不要看一下原po回文的 IamFunction 方法簽名再想想為什麼這樣寫? 這樣看不懂我也不解釋了另外 這邊的抽象物件 (Father也好 Family也好)認識 StreamReader 本身就是..嗯..所謂的"新手"寫法了..基本上 這個案例根本牽扯不上 DesignPattern 所以我還特別在原範例中跳過 Factory 以免模糊焦點我還真閒... 1. 不知道你是不是看出原po"已經"繼承類別了2. 如果用偷懶解釋的話 那所有的 dirty code 都是合理的我們也不需要再往下討論了3. 我不知道 "son is father" 成不成立 至少已知資訊中沒有超能力是看不出來的 我只能從物件行為判斷4. 物件導向設計原則中 只有依賴倒轉原則但沒有一條告訴你 "類別不該繼續於類別"需要從framework找些 "類別繼承類別的"例子給您嗎?5. again "我寫的範例"中 沒有包括 son 繼承 father真的要說 了不起是"偷懶" 延用了既有類別最後 用抽象隔離實作是個好的習慣 但不代表永遠可以拿一句話就說別人寫錯 (更何況這句話本身就有問題)不然 你直接批我變數用 xxx strA 會不會比較快?話說大哥 你看到 IamFunction 的簽名了沒?你是沒看到還是真的看不懂?那個簽名已經知道他的 son 有繼承 father 了....還是看不懂簽名? signature?你不覺得msdn有錯 卻覺得這裡的Son繼承Father 有錯 理由?不要問這麼大的好了 這裡的son和father各是什麼類別你知道嗎? 我不清楚 因為就我看到的內容為限 只看到屬性所以 以內容為限 son繼承father 可能有錯 也可能沒錯所以在沒有更多已知的情況下 我覺得你的指教很無厘頭上面寫的5剛好被你的補充切成兩段"我寫的"範例中不包括繼承 但我有延用"既有的"類別也就是說 這是一段不改變類別設計為前提的範例不改變設計的原因是 以目前看到的內容為限沒辦法判斷 son和father 的繼承關係是不是合理言歸正傳 原PO的問題是要避免重覆程式碼結果改完後在 if 和 else 中都出現了都樣的呼叫既然都已經繼承了 所以我單純寫出一點修正來避開這個問題完全看不出你回一篇文在激動什麼 DesignPattern 的 = =如果你還是覺得這個例子中是錯的 麻煩幫我把son/father換成label/control, strA/strB換name/text再幫忙寫個信問MS 為什麼Label可以繼承非抽象類別Control
作者: ssccg (23)   2014-05-19 17:22:00
先不管son father這些名稱,為什麼類別不應該繼承類別?
作者: GoalBased (Artificail Intelligence)   2014-05-19 18:14:00
純推討論@@
作者: hoyunxian (WildDagger)   2014-05-19 21:36:00
話說使用介面和繼承基底類別到底差在哪?
作者: GoalBased (Artificail Intelligence)   2014-05-19 21:39:00
偶合性強弱的差別吧 樓上
作者: drizzt123 (drizzt)   2014-05-20 00:41:00
類別繼承類別沒有問題吧,隨便建一個winform方案,都是form1:form 在"深入淺出C#"中舉例,蜜蜂有工蜂(CLASS),"介面與防止重覆程式碼無關,而是跟讓一個類別可以應用在多種情況有關。
作者: GoalBased (Artificail Intelligence)   2014-05-20 12:59:00
這叫做工程師的浪漫
作者: StupidGaGa (笨嘎嘎)   2014-05-20 13:32:00
巨大機器人(變形金剛)與巨大怪獸(哥吉拉)是男人的浪漫
作者: ssccg (23)   2014-05-21 09:12:00
IntegerTextBox : FormattedTextBox : TextBox : Control例你Form那個例子,你覺得這是壞繼承?要繼承就是要省掉同樣的部分,為什麼還要特地從基底繼承?你說有幾個情況才能打破的 2 is的關係繼承本來大多數就是因為is的關係才繼承,怎麼變例外了?
作者: KanoLoa (卡)   2014-05-23 00:13:00
觀念很好很棒,但是拿原PO的例子根本矯枉過正...

Links booklink

Contact Us: admin [ a t ] ucptt.com