如何在Java中从main调用非静态方法?

时间:2013-12-03 03:56:24

标签: java methods main static

我一直在为我的Comp Sci入门课程做一个实验室,我遇到了这个问题:

根据说明,我必须有每个方法来回答特定问题(例如:问题5.9,方法是fivePointNine(),并且必须在main中由另一个类(Assignment6.main)调用。我的问题在于是静态的,我需要为实验室调用的最后一个方法是非静态的,因此它不允许我编译和运行。我遇到的三个错误与multiSphere(x)有关。具体错误是“无法生成从Assignment6类型静态引用非静态方法'multiSphere(double)'。“

public class Assignment6
{
public Sphere newSphere = new Sphere();
public Assignment6 A6 = new Assignment6();
public static int x;
public static void main(String[] args)
{
       x = 2 + (int)(Math.random() * ((10 - 2) + 1));
   multiSphere(x);

   x = 2 + (int)(Math.random() * ((10 - 2) + 1));
   multiSphere(x);

   x = 2 + (int)(Math.random() * ((10 - 2) + 1));
   multiSphere(x);
    }
    public void multiSphere(double diameter)
    {
    Sphere.inputDiameter(diameter);
    Sphere.volumeCalc(diameter);
    Sphere.surfaceAreaCalc(diameter);
    toString();
}
public String toString()
{
   return "The diameter of this sphere is " + Sphere.inputDiameter(x) + ", the volume      is " + Sphere.volumeCalc(x) + ", and the surface area is " + Sphere.surfaceAreaCalc(x) + ". ";
}

我的第二堂课名为Sphere,看起来像这样:

public class Sphere 
{
public Assignment6 newA6 = new Assignment6();
public static double volume;
public static double surfaceArea;
public static double inputDiameter(double diameter)
{
    return diameter;
}
public static double volumeCalc(double diameter)
{
    // Volume = (4.0/3.0)(pi)(r)^3
    volume = (4.0/3.0) * (Math.PI) * Math.pow((diameter/2.0), 3);
    return volume;
}
public static double surfaceAreaCalc(double diameter)
{
    // Surface area = (4)(pi)(r)^2
    surfaceArea = (4) * (Math.PI) * (Math.pow((diameter/2.0), 2));
    return surfaceArea;
}
}

我不确定如何在main方法中调用multiSphere(x)而不会遇到我遇到的错误。我觉得我错过了这么简单的事情。

4 个答案:

答案 0 :(得分:2)

关于

  

如何在Java中从main调用非静态方法?

简短回答:你没有,至少不是直接的。规范的答案是使用方法创建类的实例,然后在该实例上调用该方法,但在您的情况下,它将毫无价值,因为该类只有静态字段和方法。这使得你的toString方法在一个充满静态内容的类中毫无意义。要么使方法成为静态(并且它不是真正的toString()覆盖),要么使用非静态字段和方法创建一个真正的类。


正确的做法是从你的Sphere类中删除所有静态所有,这里的关键类,然后给它一个不错的public String toString()方法覆盖。在你发布的两个类中,它是唯一一个toString()方法有意义的类,但同样,只有它是一个真正的面向对象的类,具有非静态方法和字段。


接下来,您需要提供有意义的Sphere getter和setter方法。这样:

public static double inputDiameter(double diameter)
{
    return diameter;
}

既不是鱼也不是犯规。摆脱它并创建真正的getter和setter,getters不带参数但返回一个值,setter接受一个参数并声明返回void。


接下来,在静态main方法中,您将创建一个Sphere变量并为其指定一个新的Sphere实例。然后,您可以调用Sphere的相应方法,包括其toString()方法。


简而言之,废弃所有代码并重新开始。从最重要的一点开始 - 创建一个体面的Sphere类。然后创建Assignment类,使用main方法的类,并创建Sphere实例。

如果您仍然感到困惑,请发布您的实际作业说明,而不是您对其的解释或解释,这样我们就能确切了解您应该做些什么。


例如,使用与您的相似但不相同的相关示例:

CircleTest.java

public class CircleTest {
   public static void main(String[] args) {
      Circle circle = new Circle(10.0);
      System.out.println(circle); // calls toString()
   }
}

Circle.java

public class Circle {
   private double diameter;

   public Circle(double diameter) {
      this.diameter = diameter;
   }

   public double getDiameter() {
      return diameter;
   }

   public double calculateArea() {
      return Math.PI * diameter * diameter / 4.0;
   }

   public double calculateCircumference() {
      return Math.PI * diameter;
   }

   @Override
   public String toString() {
      String result = String.format("Circle with diameter %.2f, area %.2f, "
            + "circumference %.2f", 
            diameter, calculateArea(), calculateCircumference());
      return result;
   }
}

答案 1 :(得分:2)

这里有一个很多需要快速纠正 - 特别是即将推出的决赛。

首先,您需要了解您的Sphere课程应如何运作。 Sphere的每个实例都是它自己的事物并且知道如何做事。需要给出的所有Sphere都是它的直径(或半径),然后它可以找出它自身需要的一切。它可以计算其体积和表面积,并可以在toString中打印出来。

所以你希望Sphere看起来像这样:

public class Sphere {
    public double diameter;

    public Sphere(double diameter) {
        this.diameter = diameter;
    }

    public double volume() {
        return (4.0 / 3.0) * (Math.PI) * Math.pow((diameter / 2.0), 3);
    }

    public double surfaceArea() {
        return (4) * (Math.PI) * (Math.pow((diameter / 2.0), 2));
    }

    public String toString()
    {
       return "The diameter of this sphere is " + diameter + ", the volume is " + volume() + ", and the surface area is " + surfaceArea() + ". ";
    }
}

注意Sphere有一个构造函数,这就是我们创建Sphere的新实例的方式。我们只用直径来做。完成后,Sphere的实例可以完成Sphere所做的一切。

请注意,没有static。我不知道为什么你爱上static

你应该知道static任何东西都意味着该类的每个实例都共享它。这不适用于Sphere,因为每个实例都有自己的直径。它不像一堆Sphere分享直径。有些可能具有相同的直径,但它们仍然是它们自己的。这就像你和我如何驾驶Bentleys(一厢情愿的想法)在各方面都是相同的,但它们仍然是两种不同的汽车。当然static事情无法访问非static事物,因为非static事物需要成为可能无法使用的对象实例的一部分。

最后,在您的主要课程Assignment6中,您只需执行以下操作:

Sphere s = new Sphere(5);

创建一个直径为5的Sphere实例。现在s可以通过toString告诉我们它的体积,表面积及其描述。

我真的不确定你的任务是什么,但希望这会帮助你。

答案 2 :(得分:1)

您可以使用新实例来调用此方法:

public static void main(String[] args)
{
    Assignment6 assignment6 = new Assignment6();
    ....
    assignment6.multiSphere(x);

  ....
    assignment6.multiSphere(x);
     ....
    assignment6.multiSphere(x);
}

但程序有一些错误,请检查一下。

答案 3 :(得分:0)

首先,将变量(newSphere,A6和x)设为私有。全局变量几乎总是应该是私有的 就你的问题而言 - 不是让main方法调用multiSphere,而是创建一个对象,并在其上调用它。

public static void main(String[] args) {
    ...
    Assignment6 newAssig = new Assignment6();
    ...
    newAssig.multiSphere();
 }