在继承的类中初始化常量或其他字段的最佳方法是什么?我意识到这个例子中有很多语法错误,但这是解释我想要做的事情的最佳例子。
public abstract class Animal {
public abstract const string Name; // #1
public abstract const bool CanFly;
public abstract double Price; // price is not const, because it can be modified
public void Fly() {
if (!CanFly)
Debug.Writeln("{0}s can't fly.", Name);
else
Debug.Writeln("The {0} flew.", Name);
}
}
public class Dog : Animal {
public override const string Name = "Dog"; // #2
public override const bool CanFly = false;
public override double Price = 320.0;
}
public class Bird : Animal {
public override const string Name = "Bird";
public override const bool CanFly = true;
public override double Price = 43.0;
}
我正在努力完成的一些事情:
我知道你可以在构造函数中初始化这些字段(如果你摆脱了const),但是不能保证它们被分配。如果您将这些字段替换为属性并覆盖它们,则仍需要初始化属性的支持字段。你会如何实现这个?
它抱怨的一些语法错误:
答案 0 :(得分:21)
如果基类需要派生类提供的值,则最常用的两种方法是:
在构造函数中需要它:
public readonly double Price;
protected BaseClass(double price)
{
this.Price = price;
}
派生类必须将价格传递给构造函数:
public Derived() : base(32)
{
}
或者,将其设为抽象属性:
public abstract double Price { get; }
派生类必须提供一些返回值的方法(尽管它们获取它的位置取决于派生类,在许多情况下它提供了更大的灵活性):
public override double Price
{
get
{
return 32;
}
}
答案 1 :(得分:5)
如果要在抽象类中包含特定字段,但又不想在基类中定义它们,则可以要求实现者通过构造函数提供值。
public abstract class MyClass
{
private readonly double price;
protected MyClass(double price)
{
this.price = price
}
}
使用这样的基类,所有派生类必须为基类的构造函数提供值,否则代码将无法编译。以下是一个可能看起来如何的例子:
public class Foo : MyClass
{
public Foo() : base(42) { }
}
答案 2 :(得分:2)
您获得的错误或多或少会告诉您该怎么做。您希望对Name
和CanFly
使用抽象属性而不是字段,而Price
则是普通属性。在派生类中,抽象属性在每种情况下都是只读的并返回一个常量。在代码中:
public abstract class Animal {
public abstract string Name { get; }
public abstract bool CanFly { get; }
public double Price { get; set; }
// etc
}
public class Dog : Animal {
public override string Name { get { return "Dog"; } }
public override bool CanFly { get { return false; } }
public Dog() { Price = 320.0; }
}
// etc
答案 3 :(得分:1)
答案 4 :(得分:0)
另一个模型是创建一个虚拟的访问者(属性)。这会强制派生类实现它。
这样做的好处是'canfly'的答案可能取决于(比方说)一天中的时间。