【问题标题】:what is the extra benefit of creating constructor in java?在java中创建构造函数有什么额外的好处?
【发布时间】:2013-07-17 06:38:39
【问题描述】:

我注意到一个构造函数和一个类的简单方法做同样的工作。创建一个类的构造的确切原因是什么?如果我创建MyClass(){} 构造函数和MyClassMethod(){} 方法,它将完成与我编写这些方法和构造函数的主体部分相同的工作。那么建设的需要是什么?它有什么特殊用途吗?

【问题讨论】:

标签: java methods constructor


【解决方案1】:

构造函数和方法是两个不同的东西。您可以在其中编写相同或相似的代码这一事实无关紧要。

当一个新对象被创建时,一个构造函数被调用。如果您没有指定一个,编译器将为您创建一个默认值。这是初始化对象字段并为对象分配内存的地方。这是所有面向对象语言都有的概念。必须以某种方式初始化一个新对象。需要分配内存。在 Java 中,您不会自己管理内存(至少不是直接管理),所以这是构造函数的目的。请注意,由于始终执行构造函数,因此只要您调用例如,此行为就会强制 Person p = new Person();.

既然构造函数总是被调用,你有一个选择:你让默认构造函数执行还是你自己创建一个?也许有些字段需要以不同于默认值的方式进行初始化。或者,您可能需要在不提供某些值的情况下不允许创建对象。如果您自己定义构造函数,编译器不会为您创建默认构造函数。因此,如果我有public Person(String firstName, String lastName) {},那么我创建了一个由系统再次强制执行的特定规则:除非您提供名字和姓氏,否则无法创建 Person 类的新对象:

Person p = new Person(); // this would give a compile error
Person p = new Person("John", "Smith"); // this is the only way to create an object now

使用一种方法您无法强制执行此操作。使用您的类的程序员可能会调用您的方法,也可能不会。构造函数是对象生命周期的一部分。方法定义对象的行为

【讨论】:

    【解决方案2】:

    几点:

    1) 构造函数是设置final 实例变量的唯一方法。

    public class SomeType {
       final int x ;
       SomeType(int y){
         x=y;
       }
    }
    

    2) 具有private 构造函数的类不能被子类化。

    3) 如果你的类是子类,而基类没有默认构造函数,那么你的类中需要一个构造函数来调用超类的构造函数。

    【讨论】:

      【解决方案3】:

      使用构造函数而不是方法的好处之一是您可以确保调用了构造函数并执行了构造函数中的工作。

      语言规定要构造对象,必须调用构造函数。因此,如果您使用自定义方法来建立对象的初始状态,则需要先调用默认构造函数。当您可以在一次调用构造函数中执行工作并确保对象已正确初始化时,为什么还要进行两次方法调用?

      public class Test(){
      
          private Integer x;
      
          public Test(){
      
          }
      
          public Test(Integer x){
             this.x = x;
          }
      
          public void setX(Integer x){
             this.x = x;
          }
      
          public void doSomethingWithX(){
             this.x.toString();
          }
      }
      
      Test test = new Test(8);
      test.doSomethingWithX(); //I know x has been declared and assigned
      
      Test test = new Test();
      test.doSomethingWithX(); //X has not been assigned results in NPE
      

      【讨论】:

      • 为什么不把 x 传给 doSomethingWithX(),在那里初始化然后使用呢?
      【解决方案4】:

      如果您创建一个MyClass 的新对象,它将自动调用构造函数 - 您可以初始化其中的所有成员,并确保该对象的所有成员都已初始化。

      一般情况:
      当您创建此类的新对象时,构造函数总是调用一次,而您不能手动调用它。
      并且不要在构造函数中做“真正的”工作,因为它会减慢此类对象的创建速度 - 仅在此处初始化您的类/成员。

      你也可以根据你的需要使用不同的构造函数——但是如果你创建了一个构造函数,就没有更多的默认构造函数了!

      示例:

      public MyClass {
      
         int score;
      
         public MyClass(int sc) { // already know the score
          score = sc;
         }
      
         public MyClass() { // don´t know the score yet
          score = 1;
         }
      
         public void addScore() {
         score += 5;   // i know for sure that score is not zero 
         }
      
      }
      

      【讨论】:

        【解决方案5】:

        本质上,构造函数只是一种隐式返回其包含类型的对象的特殊方法。您通常应该使用构造函数来创建对象 - 这是人们期望看到的。

        然而,有一个有用的习惯用法叫做factory method(更多信息在this link),它本质上是使用静态方法来构造一个对象,主要优点是

        • 您可以给工厂方法一个更具描述性的名称(当然,标准构造函数必须以包含的类命名)。
        • 他们没有返回一个对象,提供了更多的灵活性。
        • 它们可以返回类的子类型。

        【讨论】:

        • 方法不叫static constructor,而是工厂方法。
        • 我的理解是,如果它返回其包含类的类型,则称为静态构造函数,否则称为工厂方法(例如,它属于专用工厂类)。然而,一点谷歌搜索表明工厂方法在这两种情况下都是通用名称,将更新我的答案。谢谢!
        【解决方案6】:

        您可以在构造函数中设置 final 字段而无需初始化器。这有助于构建 immutable 实例:

        class Number extends Expr {
            private final int n;
        
            public Number(int n) {
                this.n = n;
            }
        
            public int getValue() {
                return this.n;
            }
        }
        

        因此,在这样的构造函数之后,您可以依赖实例已完全初始化这一事实(在这种情况下,它的值是不可变/常量)。

        【讨论】:

          【解决方案7】:

          构造函数不像简单的方法。每次创建该特定类的对象时都会调用它。您不需要显式调用它。


          在创建对象时我们需要立即执行一些操作,例如,当您创建 GUI 类型的东西时,您希望在创建时设置许多属性,例如窗口大小等。 构造函数的另一个好处是类的安全性。除非您知道构造函数的正确周长,否则无法创建对象。


          更多详情:http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

          【讨论】:

            【解决方案8】:

            构造函数是面向对象编程中类或结构的一种特殊方法,用于初始化该类型的对象。

            几点:

            1. A constructor eliminates placing the default values.
            2. A constructor eliminates calling the normal method implicitly.
            

            【讨论】:

              猜你喜欢
              • 2016-12-19
              • 2012-01-27
              • 2023-03-21
              • 1970-01-01
              • 2014-08-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-04-12
              相关资源
              最近更新 更多