2012-11-20 65 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); 
     } 

    } 
}