Что лучший способ состоит в том, чтобы инициализировать константы или другие поля в наследованных классах? Я понимаю, что в этом примере существует много синтаксических ошибок, но это - лучший пример для объяснения ясно, что я пытаюсь сделать.
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;
}
Несколько вещей я пытаюсь выполнить:
Я знаю, что Вы могли инициализировать эти поля в конструкторе (если Вы избавляетесь от константы), но тогда они, как гарантируют, не будут присвоены. Если бы Вы имеете эти поля как свойства вместо этого и переопределяете их, необходимо было бы все еще инициализировать отступающее поле свойства. Как Вы реализовали бы это?
Несколько синтаксических ошибок это жалуется на:
Если базовый класс требует, чтобы значение предоставлялось производным классом, два наиболее распространенных способа:
Требовать его в конструкторе:
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;
}
}
]Если вы хотите иметь определенные поля в абстрактном классе, но не хотите определять их в базовом классе, вы можете потребовать, чтобы имплементаторы поставляли значения через конструктор. [
] [public abstract class MyClass
{
private readonly double price;
protected MyClass(double price)
{
this.price = price
}
}
]
[]С таким базовым классом все производные классы []должны [] поставлять значение в конструктор базового класса, иначе код не будет скомпилирован. Приведем один пример, как это может выглядеть:[
] [public class Foo : MyClass
{
public Foo() : base(42) { }
}
] ] Полученные ошибки более или менее говорят о том, что делать. Вы хотите использовать абстрактные свойства, а не поля, для []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
] Вы можете использовать Readly и Внутренний конструктор для обеспечения применения этого поведения, но это было бы несколько не хватало в Finese. Если вы идете с этим, наследники должны быть в том же пространстве имен / сборке, чтобы воспользоваться внутренним конструктором.
Другая модель состоит в том, чтобы создать аксессуар (свойство), который является виртуальным. Это заставляет полученные классы для его реализации.
Преимущество этого заключается в том, что «Canfly» может иметь ответ, который зависит от (сказать) время дня.