解决这个问题的最佳方法是什么?
静态成员是所有子类的一个,我想为子类使用不同的静态成员,但是名字相同,所以我可以使用vehicle.canDo;这应该给我不同的数组,取决于vechicle实例的实际类别。
我可以从canDo数组中删除静态,但同一个子类的所有实例在canDo数组中应始终具有相同的值,因此不需要在每个实例中都有canDo数组,这将是对内存的极大浪费,因为我将有太多这个班级的实例。
class Vehicle {
public static List<string> canDo;
static Vehicle() {
canDo = new List<string>();
canDo.Add("go");
}
}
class Plane : Vehicle {
static Plane() {
canDo.Add("fly");
}
}
class Ship : Vehicle {
static Ship() {
canDo.Add("sail");
}
}
class Main {
static void Main(string[] args) {
Vehicle plane = new Plane();
Vehicle ship = new Ship();
plane.canDo; // Contains (go, fly and sail) i want only (go and fly)
ship.canDo; // Contains (go, fly and sail) i want only (go and sail)
}
}
答案 0 :(得分:5)
解决这个问题的最佳方法是什么?
不要滥用非静态方法的静态方法。很简单。
静态没有继承,并且不能以任何方式拥有继承方案。
你正在通过滥用功能来打一场战斗 - 不值得战斗。请学习正确的面向对象。
答案 1 :(得分:3)
您不需要静态变量和构造函数,只需添加基础构造函数(默认情况下完成,: base()
是可选的):
class Vehicle {
public List<string> canDo;
Vehicle() {
canDo = new List<string>();
canDo.Add("go");
}
}
class Plane : Vehicle {
Plane() : base() {
canDo.Add("fly");
}
}
class Ship : Vehicle {
Ship() : base() {
canDo.Add("sail");
}
}
更新:根据@Eben Roux的评论 -
public abstract class Vehicle {
protected static List<string> _canDo;
protected abstract List<string> getCanDo();
public List<string> canDo{
{ get {
var _cando = new List();
_cando.AddRange(Vehicle._canDo);
_cando.AddRange(this.getCanDo());
return _cando;
}
}
}
static Vehicle() {
_canDo = new List<string>();
_canDo.Add("go");
}
}
class Ship : Vehicle {
protected static List<string> childCanDo;
protected override getCanDo(){
return Ship.childCanDo;
}
static Ship() {
childCanDo.Add("sail");
}
}
答案 2 :(得分:3)
请注意,您还可以使用canDo
隐藏基类的new
:
class Vehicle
{
public static List<string> canDo = new List<string>() { "go" };
}
class Plane : Vehicle
{
public new static List<string> canDo = new List<string>(Vehicle.canDo);
static Plane()
{
canDo.Add("fly");
}
}
答案 3 :(得分:2)
每种类型都需要canDo
列表的实例。因此,您可以通过构造函数传递集合,也可以在子类型级别上使用静态。
编辑(详细说明):
由于您的子类实例都具有相同的能力&#39;并且您不希望为每个需要共享列表的列表填充列表。您正在使用可能需要合成的继承:
public abstract class Vehicle
{
protected List<string> canDo;
protected Vehicle(List<string> canDo)
{
this.canDo = canDo;
}
}
public class Plane : Vehicle
{
public Plane(List<string> canDo) : base(canDo)
{
}
}
我也不会使用List<string>
,而是将其封装在一个具有商业意义的类中(尽管我知道这只是一个例子)。要填充canDo
列表,您可以在子类型上使用工厂或工厂方法。
有很多方法可以做到这一点,你需要找到一些舒适的东西。
虽然我确实提出了静态作为替代方案(因为你问的是)我绝对不会自己使用静态。