2015-01-06 5 views
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 Я получаю как описано выше. Не могу понять почему?

+3

Это много кода для чтения. Можете ли вы сконденсировать это, чтобы показать только соответствующую информацию? Вы можете решить это самостоятельно, если хотите. – Hayden

ответ

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 непосредственно.

Аналогично, вагонетки строится непосредственно, используя тот же 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 от статического в более контролируемых и Потокобезопасную моды.

Наконец, базовые классы также могут использовать авто свойства, вместо явных методов геттерных, т.е. заменить

public float GetWeight() 
{ 
    return Weight; 
} 

с

public Weight {get; private set;} 
+1

Спасибо за усилия StuartLC и вашу помощь; однако я ограничен тем, что я могу сделать или кодировать с требованиями контрольной точки, например: – fildar

+0

Спасибо за усилия StuartLC и вашу помощь; однако я ограничен тем, что я могу сделать или кодировать с требованиями контрольной точки, например: в классе StockItem у меня могут быть CostPrice, Description, LastStockNumber и StockNumberFields и getCostPrice, Print и StockItemMethods. Я ничего не могу добавить. Во всяком случае, я буду обдумывать ваши предложения. – fildar

1

Вашего конструктором для StockItem, который принимает конкретный StockNumber является вызывающий другой конструктор, который увеличивает LastStockNumber. Поэтому каждый раз, когда вы создаете экземпляр StockItem (или что-то, что происходит от StockItem), LastStockNumber будет увеличиваться, даже если в конструкторе указан номер запаса.

На самом деле, вы увеличиваете число LastStockNumber во многих конструкторах, что приведет к тому, что он будет увеличиваться, по крайней мере, дважды, когда вы создаете некоторые типы объектов.


Edit:

касается того, как это исправить, я бы начать с изменения StockItem конструктор, который использует LastStockNumber так, что вместо того, чтобы вызывать другой конструктор, он просто устанавливает цену и само описание:

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

Тогда я удалить везде, что вы увеличиваете LastStockNumber в конструкторах производных классов.

Вы также должны сделать LastStockNumber частным. После внесения этих изменений, если вы продолжаете создавать объекты так, как вы, то LastStockNumber никогда не будет увеличиваться, потому что вы всегда указываете номер запаса при создании объекта.

+0

Спасибо за ответ, теперь я вижу проблему, чтобы выяснить, как ее исправить !!!! – fildar

+0

Это требования, которые мне необходимо выполнить « – fildar

+0

- StockItem содержит статическое поле, которое поддерживает значение последнего используемого количества акций (с инициализацией до 10000) – fildar