0

这是我的代码:

class StockItem
{
    internal float CostPrice;
    internal string Description;
    internal static int LastStockNumber = 10000;
    internal int StockNumber;

    public StockItem(int StockNumber, string Description, float CostPrice): this(Description, CostPrice)
    {
        this.StockNumber = StockNumber;
    }

    public StockItem(string Description, float CostPrice)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
        this.CostPrice = CostPrice;
        this.Description = Description;
    }

    public float GetCostPrice()
    {
        return CostPrice;
    }

    public virtual string Print() //is virtual (Polymorphic)
    {
        string Output = "";
        Output += "\r\n\r\n";
        Output += "Stock Item: ";
        Output += "\r\n";
        Output += "Stock No: " + StockNumber;
        Output += "\r\n";
        Output += "Desc: " + Description;
        Output += "\r\n";
        Output += "Cost: " + CostPrice;
        Output += "\r\n";
        return Output;
      }
    }
}

class HeavyStockItem : StockItem
{
    internal float Weight;

    public HeavyStockItem(int StockNumber, string Description, float CostPrice, float Weight)
        : base(StockNumber, Description, CostPrice)
    {
        this.Weight = Weight;
    }

    public HeavyStockItem(string Description, float CostPrice, float Weight)
        : base(Description, CostPrice)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
        this.Weight = Weight;
    }

    public float GetWeight()
    {
        return Weight;
    }

    public override String Print() //overriding StockItem.Print and adds wieght to the bottom 
    {
        string Output = "";
        Output += base.Print();
        Output += "Weight: " + Weight + "\r\n";
        return Output;
      }
    }
}

class CarEngine : HeavyStockItem
{
    internal string EngineNumber;

    public CarEngine(int StockNumber, string Description, float CostPrice, float Weight, string EngineNumber)
        : base(StockNumber, Description, CostPrice, Weight)
    {
        this.EngineNumber = EngineNumber;
    }

    public CarEngine(string Description, float CostPrice, float Weight, string EngineNumber)
        : base(Description, CostPrice, Weight)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
    }

    public override String Print() //overriding StockItem.Print and adds engine number to the bottom 
    {
        string Output = "";
        Output += base.Print();
        Output += "EngineNumber: " + EngineNumber + "\r\n";
        return Output;
    }
  }
}

public partial class Form1 : Form
{
    StockItem StockItem1;
    CarEngine StockItem2;
    CarEngine StockItem3;
    StockItem StockItem4;
    HeavyStockItem StockItem5;

    private void ShowItem (StockItem PrintStockItem)
    {
        txtOutput.Text += PrintStockItem.Print();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        StockItem1 = new StockItem(StockItem.LastStockNumber, "Scrediwer set", 42);
        StockItem2 = new CarEngine(8025, "MazdaB6T", 1252, 800, "Z4537298D");
        StockItem3 = new CarEngine(StockItem.LastStockNumber, "Holden 308", 958, 1104, "P74623854S");
        StockItem4 = new StockItem(8002, "Trolley Jack", 127);
        StockItem5 = new HeavyStockItem(HeavyStockItem.LastStockNumber, "JD Caterpillar Track", 3820, 2830);
    }

    private void btnList_Click(object sender, EventArgs e) //polymorfic call
    {
        ShowItem(StockItem1);
        ShowItem(StockItem2);
        ShowItem(StockItem3);
        ShowItem(StockItem4);
        ShowItem(StockItem5);
    }
  }
}

这是我的输出:

Stock Item: 
Stock No: 10000
Desc: Scrediwer set
Cost: 42

Stock Item: 
Stock No: 8025
Desc: MazdaB6T
Cost: 1252
Weight: 800
EngineNumber: Z4537298D

Stock Item: 
Stock No: 10002
Desc: Holden 308
Cost: 958
Weight: 1104
EngineNumber: P74623854S

Stock Item: 
Stock No: 8002
Desc: Trolley Jack
Cost: 127

Stock Item: 
Stock No: 10004
Desc: JD Caterpillar Track
Cost: 3820
Weight: 2830

我的问题是:

而不是让项目 1,3 和 5 的库存编号为 10000、10001 和 10002,我按照上述方式获得。无法理解为什么?

4

2 回答 2

1

StockItem接受特定 StockNumber 的构造函数正在调用另一个递增的构造函数LastStockNumber。因此,每次创建 的实例StockItem(或派生自 的东西StockItem)时,LastStockNumber都会递增,即使在构造函数中指定了库存编号。

事实上,您LastStockNumber在许多构造函数中递增,这将导致在创建某些类型的对象时它至少递增两次。


编辑:

至于如何解决这个问题,我将从更改StockItem使用 LastStockNumber 的构造函数开始,这样它就不会调用其他构造函数,而只是设置价格和描述本身:

public StockItem(int StockNumber, string Description, float CostPrice)
{
    this.StockNumber = StockNumber;
    this.CostPrice = CostPrice;
    this.Description = Description;
}

LastStockNumber然后我会删除你在派生类的构造函数中增加的其他任何地方。

您还应该将其设为LastStockNumber私有。进行这些更改后,如果您继续按原样创建对象,则LastStockNumber永远不会增加,因为您始终在创建对象时指定库存编号。

于 2015-01-06T05:10:58.557 回答
0

CarEngine你正在调用的构造函数,

    StockItem2 = new CarEngine(8025, "MazdaB6T", 1252, 800, "Z4537298D");

public CarEngine(int StockNumber, string Description, float CostPrice, 
                 float Weight, string EngineNumber)
    : base(StockNumber, Description, CostPrice, Weight)

依次调用以下基类构造函数:

public StockItem(int StockNumber, string Description, float CostPrice): this(Description, CostPrice)
{
   this.StockNumber = StockNumber;

直接设置 StockNumber。

类似地,Trolley 直接使用相同的 StockItem 构造函数构造:

  StockItem4 = new StockItem(8002, "Trolley Jack", 127);

看起来,您想调用另一个 StockItem 构造函数,即递增静态计数器的构造函数:

 public StockItem(string Description, float CostPrice)

顺便说一句,请注意,如果您使用浮点变量来存储货币,您可能会遇到舍入问题,例如float CostPrice. 我建议decimal改用。

编辑

FWIW 我将按StockItem如下方式重新设计您的基类,以封装属性并控制递增库存编号的分配。另请注意,静态变量容易出现线程安全问题。

internal class StockItem
{
    // Private to prevent externals + subclasses from mutating this
    private static int _lastStockNumber = 10000;

    // Convert to properties and private setters force subclasses to use the Ctor
    public decimal CostPrice { get; private set; }
    public string Description { get; private set; }
    public int StockNumber { get; private set; }

    // Static is now read only
    public static int LastStockNumber
    {
        get { return _lastStockNumber; }
    }

    // Constructor not allowing for setting of Stock Number
    public StockItem(string description, decimal costPrice)
    {
        Interlocked.Increment(ref _lastStockNumber);
        this.CostPrice = costPrice;
        this.Description = description;
    }

    // Constructor allowing for direct setting of stockNumber
    public StockItem(int stockNumber, string description, decimal costPrice)
    {
        this.StockNumber = stockNumber;
        this.CostPrice = costPrice;
        this.Description = description;
    }
}

以上将强制子类使用上述构造函数之一来设置基类属性,并且如果适用,以更受控制和线程安全的方式从静态自动分配 StockNumber。

最后,基类也可以使用自动属性,而不是显式的 getter 方法,即替换

public float GetWeight()
{
    return Weight;
}

public Weight {get; private set;}
于 2015-01-06T05:03:02.910 回答