Cannot invoke "WashingMachine.WashingMachine.setPowderType(int)" because "this.washingMachine[this.counter]" is null

Не получается никак освоить java и понять как корректно работать с классами. В данном случае у меня выдаёт ошибку:

Cannot invoke "WashingMachine.WashingMachine.setPowderType(int)" because "this.washingMachine[this.counter]" is null

Задача:

1.​ Разработать модель прачечной, состоящей из следующих классов:

a.​ Белье: температура стирки, температура глажения.

b.​ Цветное белье: цвет белья (перечисление: светлое, темное, цветное).

c.​ Стиральная машина: тип порошка и кондиционера, цвет стираемого белья, температура стирки.

2.​ Определить метод Load, который будет заполнять стиральную машину одним типом белья (с одинаковыми параметрами стирки).

3.​ Переопределить метод toString у белья.

4.​ Разработать программу для демонстрации описанных классов.


Controller.java:

package Controller;

import java.util.Scanner;

import Source.Source;
import Clothes.Clothes;
import Clothes.ColoredClothes;
import WashingMachine.WashingMachine;

public class Controller {
    
    // Default int state.
    private int defaultInt = 100;
    
    // Variable for counting the total number of washing machines.
    private int counter = 0;
        
    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }
    
    // Announcement a washing machine.
    WashingMachine[] washingMachine;
    
    // Announcement underwear.
    Clothes[] clothes;
    
    // Define the Load method that will fill the washing machine with one type of laundry (with the same washing parameters).
    Controller Load(Controller controller) {
        
        // Setting the powder type to default state.
        washingMachine[counter].setPowderType(defaultInt);
        
        // Setting the type of air conditioner to default state.
        washingMachine[counter].setConditionerType(defaultInt);
        
        // Setting the washing temperature to the default position.
        clothes[counter].setWashingTemperature(defaultInt);
        
        // Setting the ironing temperature to the default position.
        clothes[counter].setIroningTemperature(defaultInt);
        
        return controller;
    }
    
    public Controller() {
        
        //
        washingMachine = new WashingMachine[100];
        
        //
        clothes = new Clothes[100];
    }
    
    public static void main(String[] args) {
    
        try (
        Scanner console = new Scanner(System.in)) {
            
            // Responsible for the operation of the application is still true.
            boolean application = true; 
            
            // Implementation of long-term operation of the application.
            while (application) {

                // The announcement of a certain laundry, in our case it's just a controller.
                Controller controller = new Controller();
                
                // Starting message.
                System.out.print("Laundry model version 1.0.0\n\n");
                
                // Main Menu Messages
                System.out.print("[1] - Shut down the application.\n");
                System.out.print("[2] - Demonstration of the Load method.\n");
                System.out.print("[3] - Fill the washing machine.\n\n");
                
                // Message about the request to enter data.
                System.out.print("Enter the operation number: ");
                
                // The value that the user selects in the menu will be saved here.
                int point = console.nextInt();
                
                // Implementation of the menu item selection.
                switch (point) {
                
                    // End the programm.
                    case 1: {
                        
                        //Interrupting the main application loop.
                        application = false;
                        
                        break;
                    }
                    
                    // Demonstration of the "Load" method.
                    case 2: {
                        
                        // Announcement source.
                        Source source = new Source();
                        
                        // Getting the number of filled washing machines + passing to the Load method.
                        controller.Load(controller);
                        
                        // Displays data on the screen immediately after filling.
                        source.WashingMachineDataShow();
                        
                        int counter = controller.getCounter();
                        controller.setCounter(counter++);
                        
                        break;
                    }
                    
                    // Filling the washing machine manually.
                    case 3: {
                        
                        break;
                    }
                }
            }
        }
    }
}

WashingMachine.java:

package WashingMachine;

import Controller.Controller;

// Washing machine: type of powder and conditioner, color of laundry, washing temperature.
public class WashingMachine extends Controller {
    
    // Default int state.
    private int defaultInt = 0;
    
    // Washing machine: type of powder.
    private int powderType;

    public int getPowderType() {
        return powderType;
    }

    public void setPowderType(int powderType) {
        this.powderType = powderType;
    }
    
    // Washing machine: type of conditioner.
    private int conditionerType;

    public int getConditionerType() {
        return conditionerType;
    }

    public void setConditionerType(int conditionerType) {
        this.conditionerType = conditionerType;
    }
    
    public WashingMachine() {
        
        //
        powderType = defaultInt;
        
        //
        conditionerType = defaultInt;
        
    }
}

Clothes.java:

package Clothes;

import Controller.Controller;

// Linen: washing temperature, ironing temperature.
public class Clothes extends Controller{

    // Default int state.
    private int defaultInt = 0;
    
    // Linen: washing temperature.
    private int washingTemperature;
    
    public int getWashingTemperature() {
        return washingTemperature;
    }

    public void setWashingTemperature(int washingTemperature) {
        this.washingTemperature = washingTemperature;
    }

    // Linen: ironing temperature.
    private int ironingTemperature;
    
    public int getIroningTemperature() {
        return ironingTemperature;
    }

    public void setIroningTemperature(int ironingTemperature) {
        this.ironingTemperature = ironingTemperature;
    }
    
    public Clothes() {
        
        //
        washingTemperature = defaultInt;
        
        //
        ironingTemperature = defaultInt;
    }
}

ColoredClothes.java:

package Clothes;

//
public enum ColoredClothes { Light, Dark, Colored }

Source.java:

package Source;

import Clothes.Clothes;
import Controller.Controller;
import WashingMachine.WashingMachine;

// Data output and validation. They are placed in a separate class so that they do not get in the way.
public class Source {
    
    // The announcement of a washing machine.
    WashingMachine washingMachine;
    
    // The announcement of a clothes.
    Clothes clothes;
    
    // Output of washing machine filling data in tabular form.
    public void WashingMachineDataShow() {
        System.out.print("=============================================");                                    System.out.println();
        System.out.print("               Washing Machine               ");                                    System.out.println();
        System.out.print("=============================================");                                    System.out.println();
        System.out.print(" Type of powder       |  "); System.out.print(washingMachine.getPowderType());      System.out.println();
        System.out.print(" Type of conditioner  |  "); System.out.print(washingMachine.getConditionerType()); System.out.println();
        System.out.print(" Washing temperature  |  "); System.out.print(clothes.getWashingTemperature());     System.out.println();
        System.out.print(" Ironing temperature  |  "); System.out.print(clothes.getIroningTemperature());     System.out.println();
        System.out.print("                      |  ");                                                        System.out.println();
        System.out.print("=============================================");                                    System.out.println();
    }   
}

Ответы (2 шт):

Автор решения: Швеев Алексей

Первым делом избавимся от counter, ведь массив сам по себе уже хранит параметр длины.

Разберём метод Load:

Controller Load(Controller controller) {
        
    // Setting the powder type to default state.
    washingMachine[counter].setPowderType(defaultInt);
       
    // Setting the type of air conditioner to default state.
    washingMachine[counter].setConditionerType(defaultInt);
        
    // Setting the washing temperature to the default position.
    clothes[counter].setWashingTemperature(defaultInt);
        
    // Setting the ironing temperature to the default position.
    clothes[counter].setIroningTemperature(defaultInt);
        
    return controller;
}

Во-первых он принимает себя же на вход, что не имеет смысла (ведь мы можем использовать ключевое слово this)

Во-вторых переименуем washinMachine в washingMachines, ведь он представляет из себя список стиральных машин, а не какой либо конкретный объект.

Первым делом инициализируем этот массив указав размер 100 (иными словами выделим область в памяти под 100 стиральных машин):

washingMachines = new WashingMachine[100];

Теперь нам надо ДЛЯ КАЖДОЙ стиральной машины установить стандартные параметры.

Для этого проходимся по каждой стиральной машине:

for (int i = 0; i < washingMachines.length; i++){
  ...
}

Инициализируем и задаём нужные нам параметры:

washingMachines[i] = new WashingMachine()
washingMachines[i].setPowderType(defaultInt);
washingMachines[i].setConditionerType(defaultInt);
washingMachines[i].setWashingTemperature(defaultInt);
washingMachines[i].setIroningTemperature(defaultInt);

Новый метод Load:

Controller Load(){
  washingMachines = new WashingMachine[100];

  for (int i = 0; i < washingMachines.length; i++){
    washingMachines[i] = new WashingMachine();
    washingMachines[i].setPowderType(defaultInt);
    washingMachines[i].setConditionerType(defaultInt);
    washingMachines[i].setWashingTemperature(defaultInt);
    washingMachines[i].setIroningTemperature(defaultInt);
  }

  return this;
}
→ Ссылка
Автор решения: Nowhere Man

Вы создаёте массивы стиральных машин и одежды в конструкторе Controller:

public Controller() {
        //
    washingMachine = new WashingMachine[100];        
        //
    clothes = new Clothes[100];
}

но эти массивы будут заполнены сотней null-ов, а не соответствующих экземпляров, у которых можно было бы вызывать сеттеры.

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

private static WashingMachine[] createWashers(int num) {
    WashingMachine[] arr = new WashingMachine[num];
    for (int i = 0; i < arr.length;) {
        arr[i++] = new WashingMachine();
    }
    return arr;
}

либо Stream API:

private static WashingMachine[] createWashers(int num) {
    return Stream.generate(WashingMachine::new)
        .limit(num)
        .toArray(WashingMachine[]::new);
}

Аналогичный метод Clothes[] createClothes(int num) следует создать и для одежды.

Затем в конструкторе контроллера вызываются эти методы.

public Controller() {
    //
    washingMachine = createWashers(100);        
    //
    clothes = createClothes(100);
}

Тогда метод Load можно было бы переписать, чтобы "загружать" нужный элемент массива значениями Controller.defaultInt:

public void Load(int i) {
    washingMachine[i].setPowderType(defaultInt);
    // ...  и т.д.
}
→ Ссылка