3

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

假设我有一个抽象类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; } }
}

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

你会怎么做?

4

1 回答 1

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的信息

于 2012-10-11T14:24:38.813 回答