Java中构造函数的用途?

gat*_*tor 19 java methods constructor function

构造函数的目的是什么?我一直在学习Java,在我看来,构建器在我们迄今为止所完成的工作中基本上是多余的.如果出现一个目的还有待观察,但到目前为止对我来说似乎毫无意义.例如,以下两段代码之间有什么区别?

public class Program {    
    public constructor () {
        function();
    }        
    private void function () {
        //do stuff
    }    
    public static void main(String[] args) { 
        constructor a = new constructor(); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我们被教导如何做任务的事情,但下面不会做同样的交易吗?

public class Program {    
    public static void main(String[] args) {
        function();
    }        
    private void function() {
        //do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

构造函数的目的让我感到惊讶,但到目前为止我们所做的一切都非常简陋.

Lot*_*NSW 45

构造函数用于初始化类的实例.您可以使用构造函数来创建新对象,通常使用参数指定初始状态或有关对象的其他重要信息

官方Java教程:

类包含构造函数被调用,以创建类蓝图对象.构造函数声明看起来像方法声明 - 除了它们使用类的名称并且没有返回类型.例如,Bicycle有一个构造函数:

public Bicycle(int startCadence, int startSpeed, int startGear) {
    gear = startGear;
    cadence = startCadence;
    speed = startSpeed;
}
Run Code Online (Sandbox Code Playgroud)

要创建一个名为的新Bicycle对象myBike,new运算符将调用构造函数:

自行车myBike =新自​​行车(30,0,8);

new Bicycle(30, 0, 8) 在内存中为对象创建空间并初始化其字段.

虽然Bicycle只有一个构造函数,但它可能有其他构造函数,包括一个无参构造函数:

public Bicycle(){gear = 1; cadence = 10; 速度= 0; }

Bicycle yourBike = new Bicycle(); 调用无参构造函数来创建一个名为yourBike的新Bicycle对象.

  • 要么你没有理解他,要么他不明白什么构造函数对它们都有用.假设你的程序是一个纸牌游戏:你想要一个名为Card的52个实例,每个实例都有一个数字和一个颜色.构造函数用于创建类Card的实例.并且你需要调用它52次才能拥有52张卡:`new Card(1,"hearts")`等等.现在每个Player的实例(你还需要一个构造函数),可以有一个List(构造)使用构造函数)的卡片.阅读介绍性的Java书籍或官方Java教程. (12认同)
  • 干杯,这清除了我的困惑.设置默认或初始参数是有意义的,但到目前为止我们所做的一切都不需要.我想当我们需要保持一致性时,我们正在做好准备. (2认同)
  • 无论是谁投资我,都要小心解释原因?从我的回答来看,我绝对不会以任何方式损害OP对构造函数的了解.:/ (2认同)
  • @LotusUNSW我觉得这里有一个downvoter-troll.你的答案很棒. (2认同)
  • @AJMansfield - 不是这样.您可以在超类中添加其他构造函数,并且仍然在子类中使用默认构造函数,只要超类包含一个没有参数且没有`throws`子句的显式可访问构造函数.一个类可以包含多个构造函数.要提供的构造函数的选择可以基于可以使用哪些参数集来初始化实例.有时这些参数*必须在构造函数中指定,因为它们在实例中是不变的. (2认同)

Aki*_*ira 29

构造函数基本上是一种方法,可用于确保类的对象天生有效.这是构造函数的主要动机.

假设您希望您的类具有单个整数字段,该字段应始终大于零.你怎么以可靠的方式做到这一点?

public class C {
     private int number;

     public C(int number) {
        setNumber(number);
     }

     public void setNumber(int number) {
        if (number < 1) {
            throws IllegalArgumentException("C cannot store anything smaller than 1");
        }
        this.number = number;
     }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,您可能看起来正在做一些多余的事情,但事实上,无论如何,您都要确保该数字始终有效.

"初始化类的实例"是什么一个构造函数,但不是这个原因,为什么我们有构造函数.问题是关于构造函数的目的.您还可以c.setNumber(10)在外部初始化类的实例,在上面的示例中使用.因此构造函数不是初始化实例的唯一方法.

构造函数以一种安全的方式执行此操作.换句话说,只有一个类解决了确保其对象始终处于有效状态的整个问题.不使用构造函数会将此类验证留给外部世界,这是糟糕的设计.

这是另一个例子:

public class Interval {
    private long start;
    private long end;

    public Interval(long start, long end) {
        changeInterval(start, end);
    }

    public void changeInterval(long start, long end) {
        if (start >= end) {
            throw new IllegalArgumentException("Invalid interval.");
        }
        this.start = start;
        this.end = end;
    }
    public long duration() {
        return end - start;
    }
}
Run Code Online (Sandbox Code Playgroud)

Interval类表示时间间隔.使用long存储时间.在开始之前结束的间隔没有任何意义.通过使用像上面那样的构造函数,在系统中的任何给定时刻都不可能有一个Interval实例来存储一个没有意义的区间.

  • +1是实用的答案.这个答案不仅满足了定义,还满足了我的WHY查询."生来有效"是我用来构建使用构造函数的必要性的一小部分"有用性". (4认同)

Pra*_*eek 10

正如LotusUNSW中提到的,答案构造函数用于初始化类的实例.

例:

假设你有Animal类似的课程

class Animal{
   private String name;
   private String type;
}
Run Code Online (Sandbox Code Playgroud)

让我们看看当你尝试创建一个Animal类的实例时会发生什么,比如Dog命名Puppy.现在你必须初始化name = Puppytype = Dog.那么,你怎么能这样做.一种方法是使用类似的构造函数

    Animal(String nameProvided, String typeProvided){
         this.name = nameProvided;
         this.type = typeProvided;
     }
Run Code Online (Sandbox Code Playgroud)

现在,当您创建类的对象时Animal,Animal dog = new Animal("Puppy", "Dog");会调用类似于构造函数的内容,并将名称和类型初始化为您提供的值,即Puppy和Dog.

现在你可能会问,如果我没有为我的构造函数提供类似的参数

Animal xyz = new Animal();
Run Code Online (Sandbox Code Playgroud)

这是default Constructor使用默认值初始化对象,即在我们的Animal类中name,type对应的xyz对象将是name = nulltype = null

  • +1为一个好的答案.简洁明了.保持! (2认同)