Java — Ошибка в системе магазина

#java #debugging #methods #inventory-management #shop

#java #отладка #методы #управление запасами

Вопрос:

итак, у меня есть небольшое взаимодействие между инвентарем и магазином, для которого я не могу найти решение.

Предполагается, что игрок может покупать и продавать предметы с предопределенной стоимостью покупки / продажи в моем конструкторе класса Item. С помощью сканера я могу продавать без каких-либо ошибок. Однако, если я покупаю какое-либо количество, все количество покупается каким-то образом. Количество товара устанавливается равным 0 после того, как я покупаю любое количество один раз.

     private void buyItem() {
    System.out.println("Which item would you like to buy?");
    showStock();

    @SuppressWarnings("resource")
    Scanner sc = new Scanner(System.in);
    String itemName = ""   sc.next();
    
    for (int i = 0; i < store.length; i  ) {
        if (store[i] != null amp;amp; store[i].getName().equals(itemName)) {
            // Checks if the given item name is available in the store
            System.out.println("We have "   store[i].getQuantity()   " "   store[i].getName()   "s in our stock. "   store[i].getBuyPrice()   " each");
            System.out.println("How many would you like to buy?");
            int buyQuantity = sc.nextInt();
            // Checks if there is enough in the stock
            if (buyQuantity > store[i].getQuantity()) {
                System.out.println("Not enough "   store[i].getName()   " available in the stock.");
                break;
            } else {
                // Checks if Player can afford it
                if (Player.getInstance().getCoins() >= store[i].getBuyPrice()) {
                    // Update player inventory
                    Player.getInstance().removeCoins(buyQuantity * store[i].getBuyPrice());
                    Item item = store[i];
                    item.setQuantity(buyQuantity);
                    Player.getInstance().getInv().addItem(item);
                    
                    // Buy transaction
                    store[i].setQuantity(store[i].getQuantity() - buyQuantity);
                    System.out.println("You have purchased "   buyQuantity   "x "   itemName);
                    System.out.println("Coins: "   Player.getInstance().getCoins());
                    
                    // Checks if the entire amount has been bought
                    if (buyQuantity == store[i].getQuantity()) {
                        store[i] = null;
                        System.out.println("That's all "   itemName   " the store had");
                    }
                    break;
                } else {
                    System.out.println("You don't have enough coins to buy "   buyQuantity   " "   itemName   "s");
                    break;
                }
            }

        }
    }
}
  

И это мой консольный вывод из примера:

 Which item would you like to buy?
Slot 0: Weapon
Slot 1: Cake
Slot 2: Arrow
Arrow
We have 100 Arrows in our stock. 2 each
How many would you like to buy?
10
You have purchased 10x Arrow
Coins: 980
That's all Arrow the store had
  

Я пытался и думал довольно долгое время, но я не могу выяснить свою ошибку. У вас есть какие-либо предложения? Я попробовал отладку, и все «работало», значения были правильными. Но когда я ввел количество, которое я хотел бы купить, мой вывод int ни на что не повлиял. Был бы очень признателен за любой совет!

Ответ №1:

Строка

 Item item = store[i];
  

не создает копию, но ссылается на тот же объект, который хранится в массиве store . Следующее

 item.setQuantity(buyQuantity); 
  

задает количество товара в store на buyQuantity и следующее

 store[i].setQuantity(store[i].getQuantity() - buyQuantity);
  

эффективно уменьшает количество предметов до 0 (как в магазине, так и в инвентаре игрока).

Что касается исправления, можно было бы использовать, clone() но это считается сломанным.

Я бы предложил семантически иной подход. Каждый элемент представляет собой не отдельный элемент, а набор элементов. Таким образом, определенная сумма может быть добавлена или удалена в / из пакета. Чтобы это было осуществимо, я бы сделал общий суперкласс Item (который, как я предполагаю, существует) универсальным в T extends Item<T> , abstract и дал ему public abstract T take(int amount); метод:

 public abstract class Item<T extends Item<T>> {
    ...
    public abstract T take(int amount);
    ...
}
  

Затем я бы изменил все подклассы, чтобы расширить этот суперкласс, например

 public class Arrow extends Item<Arrow> {
    public Arrow take(int amount) {
        ...
    }
}
  

Наконец, я бы переименовал классы, чтобы четко отразить, что каждый из них Item представляет собой набор элементов. Например, Item может быть переименован в ItemBundle и Arrow может быть переименован в ArrowBundle или Arrows .

Комментарии:

1. О, это имеет смысл

2. Итак, нужен ли мне метод clone в моем классе Item для устранения этой проблемы? Или какой был бы наилучший подход?

3. Что ж, clone() это возможно, но считается неисправным . Дайте мне минутку подумать об этом.

4. Спасибо за ваше время и решение! Приветствия

Ответ №2:

Вы явно меняете количество купленного товара на сумму, запрошенную игроком здесь:

 Item item = store[i];
item.setQuantity(buyQuantity);
  

Если вы хотите добавить x единиц Item инвентаря игрока, вам нужно создать новый экземпляр того, Item для которого вы установили buyQuantity ту сумму, которая была куплена. Таким образом, вы сохраняете целостность запасов магазина.