这是我的代码:
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和1号商品的库存号5为10000,10001& 10002我按上述方式得到。不明白为什么?
答案 0 :(得分:1)
接受特定StockNumber的StockItem
构造函数正在调用增加LastStockNumber
的其他构造函数。因此,每次创建StockItem
的实例(或从StockItem
派生的内容)时,即使在构造函数中指定了库存号,LastStockNumber
也会递增。
实际上,您在许多构造函数中递增LastStockNumber
,这会导致在创建某些类型的对象时它至少增加两次。
修改强>
至于如何解决这个问题,我首先要改变使用LastStockNumber的StockItem
构造函数,这样它就不会调用其他构造函数,而只是设置价格和描述本身:
public StockItem(int StockNumber, string Description, float CostPrice)
{
this.StockNumber = StockNumber;
this.CostPrice = CostPrice;
this.Description = Description;
}
然后我删除你在派生类的构造函数中增加LastStockNumber
的其他地方。
您还应将LastStockNumber
设为私有。进行这些更改后,如果继续按照您的方式创建对象,LastStockNumber
将永远不会增加,因为您始终在创建对象时指定库存编号。
答案 1 :(得分: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;}