如何合成静态虚拟/抽象成员?

时间:2012-10-11 14:06:02

标签: c# oop

我知道语法和概念上“虚拟”和“静态”成员的概念是截然相反的,但我试图推动一下,看看是否有办法实现以下目标:

假设我有一个抽象类Animal,它有一个属性NumberOfLegs。我的Cat课程应将NumberOfLegs定义为4,而Spider应该有8个分支。我想要这样的代码(显然下面的代码不会编译):

public abstract class Animal {
  public static abstract int NumberOfLegs { get; }

  public void Walk() {
    // do something based on NumberOfLegs
  }
}

public class Cat : Animal {
  public static override int NumberOfLegs { get { return 4; } }
}

public class Spider : Animal {
  public static override int NumberOfLegs { get { return 8; } }
}

我希望它是静态的,因为它不依赖于实例;它只依赖于子类类型。

你会怎么做?

1 个答案:

答案 0 :(得分:0)

我认为最好的妥协是在每个班级中为腿数创建一个常数。常量基本上是一个只读的静态成员,对于这个例子是有意义的,否则使它成为静态。

接下来,我将为Animal类定义一个抽象属性,并覆盖每个子类。这将允许继承和多态工作,但类的每个实例仍将引用相同的值。

public abstract class Animal
{
    public abstract int NumberOfLegs { get; }

    public void Walk()
    {
        // do something based on NumberOfLegs
    }
}

public class Cat : Animal
{
    private const int NumLegs = 4;

    public override int NumberOfLegs { get { return NumLegs; } }
}

public class Spider : Animal
{
    private const int NumLegs = 8;

    public override int NumberOfLegs { get { return NumLegs; } }
}

至于不要覆盖静态方法,我知道这不是你想听到的,但这是不可能的。首先,通过指定类而不是从对象的实例中指定类,使用Animal.Legs或Cat.Legs等静态成员。因此,如果你将它定义为静态,你甚至不能从类的实例访问它,也不知道多态性(即接受泛型“动物”的函数不能得到它有多少条腿并让它调用正确的属性)。如果您对此工作原理感兴趣,建议您阅读Virtual Tables