实体 class 和封装混淆 - 如何从 main() 调用非静态方法?

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

我正在创建一个名为“Crate”的 class,它将读取一个表示对象尺寸(以英寸为单位)的整数输入文件,并输出一个包含每个项目所需的板条箱尺寸的报告。一切似乎都很好,直到我尝试测试我的方法,因为我无法从 main() 调用它们。尝试时,我收到一条错误消息,指出“无法从静态上下文中引用非静态方法 createReport()”。

我是初学者,如果有什么根本性的错误,我很乐意接受批评。我只是很好奇是否有一个简单的解决方法,以及我在 static/non-static 方法方面的知识差距。

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;
    }
}

我尝试在 main() 中声明 Scanner、PrintWriter、Crate[] 对象和 crateAmount 整数,但这只会在以后导致同样的问题,因为我无法在我的方法中使用这些变量。任何帮助将不胜感激!

Non-static 方法属于 class 的一个实例,而不是 class 本身。这就是为什么不能从 main() 访问 createReport() 方法的原因,因为 main 在静态范围内,而 createReport 不在。尝试实例化 class 的实例并在对象上调用 createReport()

例如:

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

因为 createReport 方法与其 Class Crate 的实例相关。 你必须通过 new 关键字创建一个实例,然后你可以调用它的方法 createReport.

另一种方式,如果你不想创建class的实例,你可以通过关键字static将方法声明为静态方法。然后该方法将在启动 jvm 时加载。

建议:你应该通过阅读书籍或其他文章来深入理解OOP编程