2012-11-20 90 views
1

所以我只想爲所有函數使用一個類對象,但我不想直接使用該類,而是需要訪問派生類的成員。C#Base和2派生類初始化

拿這個例子:

class A { 
    public A() { 

    } 

    public void DoSomething() { } 
} 

class B : A { 
    public B() { 

    } 

    public void DoSomethingBetter() { } 
} 

class C : A { 
    public C() { 

    } 

    public void DoSomethingBest() { } 
} 

class Runner { 
    public static void Main(String[] args) { 
     A objB = new B(); 
     objB.DoSomethingBetter(); //Won't compile 

     A objC = new C(); 
     objC.DoSomethingBest(); //Won't compile 
    } 
} 

我不希望他們初始化爲B objB =新的B(),這不是目的,我已經知道,這可能是一個解決方案。我需要爲此使用父類。

感謝

+4

請解釋這個要求的推理。 – Oded

+2

你確定你不想只重寫'DoSomething'嗎? – Magnus

回答

1

不是100%肯定你正在試圖完成的任務,但是這是如果由於某種原因你不希望重寫爲他人建議的選項。

class A { 
    public A() { 

    } 

    public void DoSomething() { } 
} 

class B : A { 
    public B() { 

    } 

    public void DoSomethingBetter() { } 
} 

class C : A { 
    public C() { 

    } 

    public void DoSomethingBest() { } 
} 

class Runner { 
    public static void Main(String[] args) { 
     A objB = new B(); 
     if (objB is B) 
      ((B)objB).DoSomethingBetter(); 

     A objC = new C(); 
     if (objC is C) 
      ((C)objC).DoSomethingBest(); 
    } 
} 

編輯:更有效的方式來做到這一點如下(它將運行2蒙上而不是4個):

class A { 
    public A() { 

    } 

    public void DoSomething() { } 
} 

class B : A { 
    public B() { 

    } 

    public void DoSomethingBetter() { } 
} 

class C : A { 
    public C() { 

    } 

    public void DoSomethingBest() { } 
} 

class Runner { 
    public static void Main(String[] args) { 
     A objB = new B(); 
     B objAB = objB as B; 
     if (objAB != null) 
      objAB.DoSomethingBetter(); 

     A objC = new C(); 
     C objAC = objC AS C; 
     if (objAC != null) 
      objAC.DoSomethingBest(); 
    } 
} 
+0

啊,這就是我在尋找,我本來試圖對我自己的(B)objB.DoSomethingBetter(),但它沒有工作,但現在我明白爲什麼我需要另一個括號。謝謝 – sl133

+3

這是一個糟糕的設計,儘管這樣做可行。它打破了B和C首先從A派生出來的全部原因。 – Joe

+0

這可能是糟糕的設計,但這就是我的程序要求 – sl133

3

如果你要聲明具有不同名稱的方法,你將不得不在實例代碼中顯式類型。

如果方法都執行相同的功能,但以不同的方式,你應該重寫從基類的方法,而不是使用不同的名稱重新實現它。

public class A 
{ 
    public virtual void DoSomething() 
    { 
     // some implementation 
    } 
} 

public class B : A 
{ 
    public override void DoSomething() 
    { 
     // body of DoSomethingBetter 
    } 
} 

public class C : A 
{ 
    public override void DoSomething() 
    { 
     // body of DomSomethingBest 
    } 
} 

應用程序的機構將簡化爲:

A b = new B(); 
A c = new C(); 

b.DoSomething() // uses logic of DoSomethingBetter 
c.DoSomething() // uses logic of DoSomethingBest 
1

是它也許是壓倒一切你正在尋找什麼?

可以使A類抽象的,它也是方法。然後把實際執行的派生類:

abstract class A { 

    public A() { 
    } 

    public abstract void DoSomething() { } 
} 

class B : A { 

    public B() { 
    } 

    public override void DoSomething() { } 
} 

class C : A { 

    public C() { 
    } 

    public override void DoSomething() { } 
} 

class Runner { 
    public static void Main(String[] args) { 
     A objB = new B(); 
     objB.DoSomething(); // Uses the B implementation 

     A objC = new C(); 
     objC.DoSomething(); // Uses the C implementation 
    } 
} 
+0

並不完全,因爲如果我在B或C中仍然有不同的方法或變量,我將不得不在A中聲明它們,而我不想這樣做。我可以在A中聲明所有變量,但是我覺得有一個更好的方法可以實現,而不會覆蓋A的所有內容。 – sl133

+0

@ sl133:這是通過'A'引用訪問任何內容的唯一方法。如果你不想使用特定的引用(或者引用參考),那麼'A'類必須知道你想做的所有事情。 – Guffa

+0

我忘了鑄造的參考,但是這就是我一直在尋找 – sl133

0

沒有看到實際的代碼,我傾向於與大家同意否則誰說你應該再次嘗試使用簡單覆蓋來解決你的問題。

不過,我有一些有趣的玩弄圍繞這一問題,並設法寫一個解決方案,它沒有鑄造。

享受!

public class BattlePlan 
{ 
    public Action<Puppy> ExecutePuppyAttack { get; set; } 
    public Action<Pigeon> ExecutePigeonAttack { get; set; } 
} 

public abstract class Animal 
{ 
    public abstract void Attack(BattlePlan battlePlan); 
} 

public class Puppy : Animal 
{ 
    public void Bite(bool barkFirst) 
    { 
     // optionally bark at the intruder, 
     // then bite as deeply as needed. 
    } 

    public override void Attack(BattlePlan battlePlan) 
    { 
     battlePlan.ExecutePuppyAttack(this); 
    } 
} 

public class Pigeon : Animal 
{ 
    public void Bombard(int altitude) 
    { 
     // ewww. nuff said. 
    } 

    public override void Attack(BattlePlan battlePlan) 
    { 
     battlePlan.ExecutePigeonAttack(this); 
    } 
} 


public class EvilMasterMind 
{ 
    private bool _puppiesMustBark = true; 
    private int _pigeonAltitude = 100; 

    public void Attack() 
    { 
     var battlePlan = new BattlePlan 
     { 
      ExecutePuppyAttack = e => e.Bite(_puppiesMustBark), 
      ExecutePigeonAttack = e => e.Bombard(_pigeonAltitude) 
     }; 

     var animals = new List<Animal> 
     { 
      new Puppy(), 
      new Pigeon() 
     }; 

     foreach (var animal in animals) 
     { 
      animal.Attack(battlePlan); 
     } 

    } 
}