5

我正在从一个类中调用一个方法,它给了我一个错误,使该方法成为静态的。当我问这个问题时,我对为什么感到困惑,构造函数中的类变量和参数有什么区别?我的理解是类变量是静态的。

患者等级:

public  String  setOption(String option) throws IOException
{
        option = stdin.readLine();
        //stuff here
    return option;
}

患者管理系统:

public class PatientManagementSystem
{
    static BufferedReader stdin = new BufferedReader(new InputStreamReader(
            System.in));
    public static void main(String[] args) throws IOException
    {
        Patient.setOption(null);    
    }
}

错误:
在此处输入图像描述

我是将方法更改为静态还是创建局部变量?

4

9 回答 9

6

根据您之前的问题,我认为可能没有完全挖掘局部变量的概念。在这种方法中:

public String setOption(String option) throws IOException
{
    option = stdin.readLine();
    return option;
}

option是一个局部变量。每次调用该变量时,您都会将该变量的初始值作为参数传递给该方法(并且您碰巧忽略了该值),但是不影响该细节,这与setOption

public String setOption() throws Exception
{
    String option = stdin.readLine();
    return option;
}

现在,局部变量与实例或类变量完全不同:它们仅在方法体内有效,并且仅在方法执行期间存在。考虑到这一点,让我们看一下这段代码:

static BufferedReader stdin = new BufferedReader(new InputStreamReader(
        System.in));
public static void main(String[] args) throws IOException
{
    Patient.setOption(null);    
}

在这里,您基本上是在将类变量误用stdin为应该是局部变量的东西:

public static void main(String[] args) throws IOException
{
    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
    Patient.setOption(null);    
}

关于您的方法调用的问题......setOption目前是一个实例方法,这意味着它必须在实例的上下文中调用。您按原样称呼它,不Patient涉及任何实例。如果您继续沿着这条路走下去,您将无法代表一个以上的患者,这可能不是您的想法。所以你想保持方法不变并创建一个实例Patient

Patient p = new Patient();
p.setOption(...);

在您的整体设计中,不清楚 setOption应该扮演什么角色,但使用静态stdin变量并不是一个好主意(我已经在上面将其设为本地)。您希望将从读取的任何数据传递stdinsetOption方法中,从而将其与输入读取逻辑分离。

于 2013-11-06T13:26:06.327 回答
5

您(可能)需要创建Patient该类的对象。

Patient myPatient = new Patient();
myPatient.setOption(null);

很难知道你想用这些有限的信息做什么。我不知道你打算对这Patient门课做什么,但我最好的猜测是?这样做是有意义的,因为您尝试使用setter命名约定调用方法。

如果您不打算实例化一个对象并走创建方法的路线setOptionstatic那么您可能应该更改方法名称。


通过更深入地解释你到底想要完成什么(甚至不谈论伪代码,只是你想要做什么的一个非常抽象的想法),在static这里解释更多会更容易(用您的具体示例)以及您应该做什么等。

于 2013-11-06T13:13:23.483 回答
3

我是将方法更改为静态还是创建局部变量?

两者都可以。

如果您的方法不使用类变量,最好将其设为静态,这样您就不必为方法调用实例化类。

于 2013-11-06T13:13:22.950 回答
3

何时制作静态与非静态的问题取决于正在建模的真实世界对象/概念。让我们Patient以这段代码中的对象为例。没有看到任何关于 的代码Patient,仍然很清楚 aPatient 什么以及它代表什么。所以,最简单的:

  • 如果您正在对特定 对象(比如说 Jane Doe)做某事Patient,那么它就不是静态的。它在一个Patient.
  • 如果您正在对 a 的概念做一些事情Patient,那么它是静态的。

所以一些非静态操作可能是:

  • 更新Patient的名称
  • Patient入院/出院
  • 转移Patient到另一个Doctor

所有这些都将涉及一个特定 Patient的,它会在某处被初始化:

var janeDoe = new Patient("Jane Doe");
// ...
janeDoe.TransferTo(doctorSmith);

我实际上在考虑一些静态方法时遇到了麻烦Patient。静态方法最常见的示例可能是工厂方法,您可以在其中获得现有的Patient或集合Patient。就像是:

var janeDoe = Patient.Fetch("Jane Doe");

或者:

var todaysPatients = Patient.Fetch(DateTime.Today);

各种辅助方法通常也是静态的,例如,可能是Patient对象上接受MedicalRecord对象并将其转换为不同格式的方法。

但总体思路是一样的。如果您正在与对象的特定实例进行交互,那么您需要该对象的实例来表示该现实世界的概念。

于 2013-11-06T13:25:02.447 回答
2

因为您直接调用该方法而不创建类对象。

什么时候有静态方法?

于 2013-11-06T13:12:41.947 回答
2

要以静态方式调用方法,您必须将其设为静态:

public static String  setOption(String option) throws IOException

但是在您的示例中,如果 stdin 不是您的 Patient 类的静态成员,它就无法工作。

总而言之,您可以按照声明为静态时调用它的方式调用方法。在静态方法中,您只能访问类的静态成员。

于 2013-11-06T13:13:31.767 回答
2

在你的试试这个main method

Patient myPatient = new Patient();
myPatient.setOption(null);
于 2013-11-06T13:14:09.313 回答
2

当我们打算将这些方法用作实用方法时,我们会创建具有静态方法的类,例如 Integer 类中的 parseInt。因此要么修改方法

public static String  setOption(String option) throws IOException // STATIC
{
    option = stdin.readLine();
    //stuff here
    return option;
}

然后使用类似的方法

    Patient.setOption(null);    

为患者实例化一个对象,例如

    Patient obj = new Patient();
    obj.setOption(null);    
于 2013-11-06T13:16:08.947 回答
2

在 Java 中 main 方法是特殊的。这是您的代码的起点。可以从代码中的任何位置调用静态方法。因此实际上它不属于包含类。main 方法也是如此。

因此,您应该在 main 方法中构造对象,然后使用构造的实例的方法。如果您不构建实例,那么您的 ide 将识别错误并建议您将其设为静态。

于 2013-11-06T13:17:52.723 回答