2

What is the best way to solve this?

A static member is one for all subclasses and i want a different static member for subclasses but with the same name so I can use vehicle.canDo; this should give me different arrays depending what class the vechicle instance really is.

I can just remove the static from canDo array but all instances of the same subclass should always have the same values in the canDo array so there is no need to have canDo array in every instances, this will be big waste of memory because i will have too many instances of this class.

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)
    }
}
4

4 回答 4

4

解决这个问题的最佳方法是什么?

不要对非静态的事物滥用静态方法。就这么简单。

静态没有继承,也不是可以以任何方式具有继承场景的东西。

您正在通过滥用功能进行战斗 - 不值得战斗。请学习正确的面向对象。

于 2012-07-03T11:48:13.423 回答
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");
    }
}
于 2012-07-03T11:49:40.167 回答
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");
    }
}
于 2012-07-03T12:00:41.930 回答
2

You need an instance of the canDo list per type. So either you can pass in the collection via the constructor or you can have a static on the subtype level.

Edit (to elaborate):

Since your sub class instance all have the same 'abilities' and you don't want to populate a list for each you would need a shared list. You are using inheritance where you probably want composition:

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)
    {
    }
}

I wouldn't go with a List<string> either but rather encapsulate it in a class that makes business sense (although I understand that this is only an example). To populate the canDo list you could go with a factory or a factory method on a subtype.

There are just so many ways to do this you will need to find something that's comfortable.

Although I did present a static as an alternative (since you were asking about it) I definitely would not use a static for this myself.

于 2012-07-03T11:46:56.730 回答