我知道语法和概念上“虚拟”和“静态”成员的概念是截然相反的,但我试图推动一下,看看是否有办法实现以下目标:
假设我有一个抽象类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; } }
}
我希望它是静态的,因为它不依赖于实例;它只依赖于子类类型。
你会怎么做?
答案 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