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;
}
Вы создаёте массивы стиральных машин и одежды в конструкторе 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);
// ... и т.д.
}