Search code examples
javaencapsulation

Entity class and encapsulation confusion - how do you call a non-static method from main()?


I am creating a class called "Crate" that will read an input file of integers representing objects dimensions in inches and output a report containing the crate sizes required for each respective item. Everything seemed fine until I tried to test my methods, as I am unable to call them from main(). When trying, I get an error message saying, "non-static method createReport() cannot be referenced from a static context."

I am a beginner, so if anything is fundamentally wrong I will happily accept criticism. I am just curious if there is a simple fix to this and what my gap in knowledge is regarding static/non-static methods.

package crate;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class Crate {
    private Crate[] crateList;
    private int crateAmount;
    private int height, width, depth, panels;
    private int smallestCratePosition, smallestCrateSize;
    private int largestCratePosition, largestCrateSize;
    private double averageCrateSize;
    
    public static void main(String[] args) throws IOException {
        createReport();
    }
    
    public Crate() {
        height = 1;
        width = 1;
        depth = 1;
        panels = 6;
    }
    
    public void createReport() throws IOException {
        Scanner infile = new Scanner(new File("ShippingSizes.txt"));
        PrintWriter outfile = new PrintWriter(new File("CrateReport.txt"));
        
        createCrateList(infile);
        
        outfile.println("There are " + crateAmount + " crates.");
        for (int i = 0; i < crateList.length; i++) {
            outfile.println(i + ": height=" + crateList[i].getHeight() + ", width=" + 
                    crateList[i].getWidth() + ", depth=" + crateList[i].getDepth() + 
                    ", panels=" + crateList[i].getPanels());
        }
        outfile.println("\n" + "Smallest crate is at " + smallestCratePosition + 
                ": height=" + crateList[smallestCratePosition].getHeight() + ", width=" + 
                crateList[smallestCratePosition].getWidth() + ", depth=" + 
                crateList[smallestCratePosition].getDepth() + ", panels=" + 
                crateList[smallestCratePosition].getPanels());
        outfile.println("Largest crate is at " + largestCratePosition + ": height," + 
                crateList[largestCratePosition].getHeight() + ", width=" + 
                crateList[largestCratePosition].getWidth() + ", depth=" + 
                crateList[largestCratePosition].getDepth() + ", panels=" + 
                crateList[largestCratePosition].getPanels());
        outfile.println("Average crate size is: " + averageCrateSize);
        
        outfile.close();
        infile.close();
    }
    
    public void setCrateDimensions(Scanner scnr) {
        int tempValue = scnr.nextInt();
        height = tempValue/12;
        if (tempValue%12 != 0)
            height++;
        
        tempValue = scnr.nextInt();
        width = tempValue/12;
        if (tempValue%12 != 0)
            width++;
        
        tempValue = scnr.nextInt();
        depth = tempValue/12;
        if (tempValue%12 != 0)
            depth++;
        
        panels = 2*((height*width)+(height*depth)+(width*depth));
    }
    
    public void createCrateList(Scanner scnr) {
        crateAmount = scnr.nextInt();
        for (int i = 0; i < crateAmount; i++) {
            crateList[i].setCrateDimensions(scnr);
        }
    }
    
    public void getSmallestCrate() {
        smallestCrateSize = crateList[0].getPanels();
        
        for (int i = 0; i < crateList.length; i++) {
            if (crateList[i].getPanels() < smallestCrateSize) {
                smallestCratePosition = i;
                smallestCrateSize = crateList[i].getPanels();
            }          
        }
    }
    
    public void getLargestCrate() {
        largestCrateSize = crateList[0].getPanels();
        
        for (int i = 0; i < crateList.length; i++) {
            if (crateList[i].getPanels() > largestCrateSize) {
                largestCratePosition = i;
                largestCrateSize = crateList[i].getPanels();
            }
        }
    }
    
    public void getAverageCrateSize() {
        double totalPanels = 0;
        for (int i = 0; i < crateList.length; i++)
            totalPanels += crateList[i].getPanels();
        averageCrateSize = totalPanels / (double)(crateList.length);
    }
    
    public int getHeight() {
        return height;
    }
    
    public int getWidth() {
        return width;
    }
    
    public int getDepth() {
        return depth;
    }
    
    public int getPanels() {
        return panels;
    }
}

I tried declaring the Scanner, PrintWriter, Crate[] object, and crateAmount integer inside of main(), however this only led to the same issue later on as I was unable to use those variables in my methods. Any help would be greatly appreciated!


Solution

  • Non-static methods belong to an instance of a class, not the class itself. This is why you can't access the createReport() method from main(), because main is in the static scope, while createReport is not. Try instantiating an instance of the class and calling createReport() on the object.

    For example:

    Crate crate = new Crate();
    crate.createReport();