【问题标题】:Java ConstructorsJava 构造函数
【发布时间】:2009-02-23 21:31:27
【问题描述】:

我正在尝试学习如何在 Java 中指定类构造函数。我开始明白它们指定了由该类创建的对象的实例变量的类型。它们也可用于设置实例变量的初始值。以下示例来自 Sun 网站上的 Java 教程:

public Bicycle(int startCadence, int startSpeed, int startGear) {
    gear = startGear;
    cadence = startCadence;
    speed = startSpeed;
}

您应该在类源代码中的什么位置放置构造函数?

这些参数是变量的名称吗?: (int startCadence, int startSpeed, int startGear) 还是 gear, cadence 和 speed 变量的名称?

(int startCadence, int startSpeed, int startGear) 与齿轮、踏频和速度有什么区别?

万一我的讲师或盐湖社区学院的任何管理员遇到这个问题,请让我明确表达我的意图。这个问题是本着学术诚信的最大精神发布的。我问这个问题是为了寻求一般建议和帮助,以了解使用 Java 编程语言的正确方法。我绝不会使用他人的作品并将其视为我自己的作品。我使用此处提供的答案作为我理解的一般帮助。我自己完成所有工作,不会复制回答我问题的人提供的工作。

【问题讨论】:

    标签: java constructor


    【解决方案1】:

    gear、cadence 和 speed 是类的成员变量(在别处声明),而 startCadence、startSpeed 和 startGear 是函数参数。

    class Bicycle
    {
        private int gear, cadence, speed;
    
        public Bicycle(int startCadence, int startSpeed, int startGear)
        {
            // set the value of member variables from passed parameters
            gear = startGear;
            cadence = startCadence;
            speed = startSpeed;
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      构造函数可以出现在类代码中的任何位置。但是,按照惯例,大多数人将它们放在任何其他非构造函数之前。

      至于变量名,这6个其实都是变量名,只是作用域不同。指定为构造函数参数的参数(startCadence、startSpeed、startGear)仅在构造函数中可用。其他 3 个(齿轮、节奏、速度)可能是类范围的变量,可用于所有方法。但是该定义未显示在您的代码 sn-p 中。整个班级看起来像这样:

      class Bicycle
      {
          // class-level variables
          private int gear;
          private int cadence;
          private int speed;
      
          // constructor
          public Bicycle(int startCadence, int startSpeed, int startGear) {
              gear = startGear;
              cadence = startCadence;
              speed = startSpeed;
          }
      
          // another method (not a constructor)
          public void ShiftUp() {
              gear = gear + 1; // notice the 'gear' variable is available here too.
          }
      }
      

      希望有帮助!

      【讨论】:

      【解决方案3】:

      你应该把构造函数放在你的类源代码的什么地方?

      我使用以下:

      package statement ....
      import statements....
      
      
      public class MyClass { 
           // instance attributes
           private int i;
      
           // class attribute 
           private static int MAX;
      
           // static methods 
           public static int getClassCount() { 
           }
      
           // Constructor!! 
           public MyClass() {  // constructor.
           }
      
           // public methods 
           // protected methods
           // private methods 
      
           // public static void main
       }
      

      但他们可以去任何地方。我觉得最好把事情按可见度排列。例如,我宁愿在私有方法之前使用公共方法(所以如果我正在寻找一个特定的公共方法,我知道它在文件的顶部)出于同样的原因,我通常将构造函数放在顶部。

      这些参数是变量的名称吗?:

      没必要,你可以随意命名。我通常使用相同的名称。

      ...或者是齿轮、节奏和速度变量的名称?...

      它们是实例变量名

      (int startCadence, int startSpeed, int startGear) 和齿轮、踏频和速度有什么区别?

      第一个是构造函数的参数名称,前者是它自己的对象的属性名称。

      取另一个样本:

       public class Person { 
           private String name; // a person has a name.
      
           public Person( String nameParameter ) {  
              this.name = nameParameter;
           }
           public String toString() { 
               return "My name is : " + this.name;
           }
      
           public static void main( String [] args )  { 
      
                // creates a new "instance" and assign "Patrick" as its name.
               Person one = new Person("Patrick");
               System.out.println( one ); // prints "My name is: Patrick"
      
               // each person have its own name. 
               Person two = new Person("Oscar");
               System.out.println( two ); // prints "My name is: Oscar"         
      
      
           } 
       }
      

      如您所见,当您将值传递给构造函数时,您使用的是参数,当您看到构造函数代码时,您会看到参数名称(接收该参数),然后将其分配给实例属性。

      【讨论】:

      • 仅供参考:在上面提到“包语句”和“导入语句”的地方,您可能有兴趣知道这些在技术上不是语句。它们被称为“指令”。仅供参考。
      • 是的。语句和指令之间的区别在于,语句导致运行时行为(通常通过直接执行机器指令),而指令仅导致编译时行为。在 Java 中,语句只能出现在方法声明和静态初始化器中。
      • ...(续)...“import”关键字充当指令,因为它告诉编译器将类定义带入本地命名空间,而不会直接导致任何运行时行为。跨度>
      • ...(续)...如果您曾经编写过编译器,您可能需要支持的基本工件列表(对于像 Java 这样的面向对象语言)将是:指令、声明、语句、表达式和运算符。
      【解决方案4】:

      我通常将构造函数放在文件顶部附近,在打包、导入、Javadoc 和静态/实例变量声明部分之后。

      gear、cadence 和 speed 是类变量,大概是在构造函数之外的某个地方定义的。 startCadence、startSpeed、startGear也是变量,不过是传递给构造函数的参数。

      您可能还会看到类似这样的内容:

      public Bicycle(int cadence, int speed, int gear) {
          this.gear = gear;
          this.cadence = cadence;
          this.speed = speed;
      }
      

      从同名参数中设置类变量。

      【讨论】:

        【解决方案5】:
        1. 这完全取决于您。我通常从所有变量开始,然后是构造函数,然后是方法,但这只是个人喜好。
        2. 参数的名称完全不相关,只要您不将它们命名为与变量相同的名称。在此示例中,gearcadencespeed 是变量。
        3. 您正在(或有人正在)将三个ints 传递给构造函数。名称(startCadencestartSpeedstartGear 称为形式参数,它们是您识别参数的方式。请参阅http://en.wikipedia.org/wiki/Parameter_(computer_science)
          gearcadencespeed 在类中的其他位置定义。类中的任何方法都可以引用它们。

        别担心 - 如果你努力工作,这种事情很快就会成为第二天性。

        哦,我可以建议您获得一个好的 IDE 吗? BlueJ 应该适合初学者,NetBeansEclipse 适合更有经验的程序员。源代码高亮是非常宝贵的。

        【讨论】:

        • 我的大学导师鼓励我们使用奥本大学开发的 jGRASP IDE。我也有你提到的三个,但没有像 jGRASP 那样使用。
        • 我从未尝试过 jGRASP,也不知道它的比较结果如何,但任何东西都比记事本好。 :)
        【解决方案6】:

        实际上,构造函数的参数不必存储为对象的成员变量。这是一个例子:

        class NumberAsString {
        
           private String numAsStr;
        
           public NumberAsString(double number) {
              this.numAsStr = Double.toString(number);
           }
        
        }
        

        在此示例中,构造函数参数实际上并未存储在任何地方,但它的值对于计算一个或多个成员变量值是必需的。

        您所看到的所有参数都直接存储为成员变量的行为很常见。特别是对于某些只为其成员变量提供“getter”和“setter”方法的类(不提供任何计算或转换函数)。在 Java 世界中,这些类通常被称为“bean”。 (是的,这是一个非常愚蠢的名字。)

        【讨论】:

          【解决方案7】:

          int startCadence 和 cadence 的基本区别不在于变量,而在于它们的作用域。如果在方法内部定义了一个变量,比如构造函数,它将只存在于该方法内部,而不存在于外部。如果在一个类中定义了一个变量,它将存在于该类中的任何地方,这样的变量具有全局范围。 变量 startCadence 只存在于构造函数中,所以如果你想在其他地方使用它的值,你可以将它传递给另一个具有全局范围的变量。这就是这里发生的事情:cadence = startCadence;

          【讨论】:

            【解决方案8】:

            1) 构造函数的位置一点也不重要。但是,按照惯例,我个人将其放置如下:

            public class Bicycle {
            
                public int gear, cadence speed;
            
                public Bicycle(int startCadence, int startSpeed, int startGear) {
                    gear = startGear;
                    cadence = startCadence;
                    speed = startSpeed;
                }
            
                public void otherFunction1() {}
                public void otherFunction2() {}
                public void otherFunction3() {}
            
            }
            

            2) 档位、踏频、速度是类的成员变量;它们属于每辆自行车,并且是每辆自行车的不同变量。然而,startCadence、startSpeed 和 startGear 是局部变量,它们只属于该函数。当我要求一个

            new Bicycle(10, 15, 5);
            

            startCadence设置为10,startSpeed设置为15,startGear设置为5。然后,构造函数将成员变量初始化为它们“start”对应的变量。

            【讨论】:

              【解决方案9】:

              (int startCadence, int startSpeed, int startGear) 参数是构造函数参数,它们将设置自行车字段cadencespeedgear。它们仅在构造函数中可用。 gearcadencespeed 是每个 Bicycle 实例唯一的实例变量,可从其他方法引用。 构造函数参数允许您为对象的初始化提供参数。在本例中,您可以创建一个档位为 1、踏频为 0、速度为 0 的自行车对象,如下所示:

              Bicycle bike = new Bicycle(0, 0, 1);
              

              或者您可以创建一个移动自行车,其节奏为 60 rpm,速度为 10 mph,在 3 档,如下所示:

              Bicycle bike = new Bicycle(60, 10, 3);
              

              构造函数的位置无关紧要,但通常构造函数放置在类定义的开头。

              【讨论】:

                【解决方案10】:
                public class Account 
                
                {
                
                    private static final Exception InsufficientFundsException = null;
                
                    private int  accountNumber;
                    private double availableBalance;
                    private int pin;
                    public Account(int account, int pin,double amount )
                    {
                
                        this.accountNumber = account;
                        this.pin = pin;
                        this.availableBalance = amount;
                    }
                
                    public void credit(double amount)
                    {
                        this.availableBalance= this.availableBalance+amount;
                    }
                
                    public void debit(double amount) throws Exception
                    {
                        if(this.availableBalance>=amount)
                        {
                        this.availableBalance= this.availableBalance-amount;
                        }
                        else
                        { 
                            throw new InsufficientFundsException();
                        }
                
                    }
                
                    public int getAccountNumber() 
                    {
                        return accountNumber;
                    }   
                
                    public double getAvailableBalance()
                    {
                        return availableBalance;
                    }
                    public String toString()
                    {
                        return "Account="+accountNumber+"pin="+pin+"balance"+availableBalance;
                    }
                    public boolean validatePIN(int pin)
                    {
                        if(this.pin==pin)
                            return true;
                        else return false;  
                }
                }
                

                【讨论】:

                • 请解释你的答案。
                • 这个问题是 5 年前提出的。没有太多解释,现在回答没有意义。
                猜你喜欢
                • 2021-07-24
                • 2013-03-21
                • 2011-09-09
                • 2010-12-11
                • 2015-05-31
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多