2012-11-03 33 views
1

我在为我的入门编程课程做家庭作业。我们最近了解了构造函数,以及它们如何工作以及它们如何工作,但我不明白为什么每个对象都需要它。这似乎只是额外的工作,因为你可以实例化对象并在它们之外运行语句。例如,在测试不同的方式来写相同的代码后,我发现,构造函数是必需的还是仅用于方便?

public class MyCartoon extends Frame { 
    StickFigure man = new StickFigure(); 
    public static void main(String[] args) {  
     new MyCartoon(); 
    } 
} 

产生正是因为这个同样的效果:

public class MyCartoon extends Frame { 
    StickFigure man; 
    public MyCartoon() { 
     man = new StickFigure(); 
    } 
    public static void main(String[] args) { 
     new MyCartoon(); 
    } 
} 

我可以请得到一些澄清?

但是,当我尝试使用上面代码实例化的另一个类中的类似代码时,它在尝试编译时会抛出100多个错误。以下代码运行良好。同样的代码,除了与StickFigure()构造函数中的代码,不会:

import wheels.users.*; 
import java.awt.Color; 

public class StickFigure { 

Ellipse head; 
Line torso; 
Line leftBackArm; 
Line leftForeArm; 
Line rightBackArm; 
Line rightForeArm; 
Line leftUpperLeg; 
Line leftLowerLeg; 
Line rightUpperLeg; 
Line rightLowerLeg; 

StickFigure() { 

    head = new Ellipse(); 
    head.setColor(Color.WHITE); 
    head.setFrameThickness(4); 
    head.setFrameColor(Color.BLACK); 
    head.setSize(80, 80); 
    head.setLocation(140, 130); 

    torso = new Line(180, 210, 160, 340); 
    torso.setColor(Color.BLACK); 
    torso.setThickness(4); 

    leftBackArm = new Line(180, 210, 145, 280); 
    leftBackArm.setColor(Color.BLACK); 
    leftBackArm.setThickness(4); 

    leftForeArm = new Line(145, 280, 132, 340); 
    leftForeArm.setColor(Color.BLACK); 
    leftForeArm.setThickness(4); 

    rightBackArm = new Line(180, 210, 190, 290); 
    rightBackArm.setColor(Color.BLACK); 
    rightBackArm.setThickness(4); 

    rightForeArm = new Line(190, 290, 225, 350); 
    rightForeArm.setColor(Color.BLACK); 
    rightForeArm.setThickness(4); 

    leftUpperLeg = new Line(160, 340, 140, 420); 
    leftUpperLeg.setColor(Color.BLACK); 
    leftUpperLeg.setThickness(4); 

    leftLowerLeg = new Line(140, 420, 105, 490); 
    leftLowerLeg.setColor(Color.BLACK); 
    leftLowerLeg.setThickness(4); 

    rightUpperLeg = new Line(160, 340, 180, 420); 
    rightUpperLeg.setColor(Color.BLACK); 
    rightUpperLeg.setThickness(4); 

    rightLowerLeg = new Line(180, 420, 180, 500); 
    rightLowerLeg.setColor(Color.BLACK); 
    rightLowerLeg.setThickness(4); 

    } 
} 

为什么会变成这样的代码,而不是第一个代码块,抛出错误没有提供的构造?

回答

10

你出什么(使用compiler-provided default constructor和变量初始化的)是好的,如果:

  • 你的初始化永远不需要抛出任何checked异常
  • 你只需要内赋值给变量初始化,而不是做什么其他。 (你可以写更复杂的代码初始化块,但如果你打算这样做,你还不如让一个构造函数。)
  • 你不需要任何参数的构造函数

在我的经验,这些都是相对很少都是真实的,特别是最后一点。当然如果你以后很乐意设置属性,你可以不用管理 - 但我个人喜欢不可变的类型,它几乎总是需要构造函数参数

那么,考虑一下你要如何写这个类没有构造函数,但保留其所有其他功能:

public class Person { 
    private final String name; 
    private final LocalDate dateOfBirth; 

    public Person(String name, LocalDate dateOfBirth) { 
     this.name = name; 
     this.dateOfBirth = dateOfBirth; 
    } 

    public String getName() { 
     return name; 
    } 

    public LocalDate getDateOfBirth() { 
     return dateOfBirth; 
    } 
} 
+0

谢谢!这解释了很多。然而,你的第一个子弹给我带来了一些困惑。我写了一些更多的代码,并且在等待答案时也尝试了包含的构造函数/无构造函数测试。新代码不需要抛出任何异常或任何其他项目符号,但是如果我拿出表示构造函数的语法,它就会失败。我将在短时间内编辑代码。 – Eunkai

+0

@refusetocompile:是的,我的例子不包括任何异常 - 但看看'FileInputStream'就是一个例子。 –

+0

您能否根据我编辑的新代码进行说明?为什么这段代码除了构造函数内部的所有语句外,都会抛出这么多的错误? – Eunkai

4

它不是你的第一个代码不使用构造函数。它的确如此。不同之处在于,它使用了编译器提供的默认构造函数,如果您不提供任何编译器,编译器会提供该构造函数。

构造函数用于初始化新创建的对象的状态。要么你明确地给你的构造函数,要么编译器自己添加一个默认的构造函数。

其实,your first code after compilation变成这样: -

StickFigure man; 
public MyCartoon() { 
    super(); 
    man = new StickFigure(); 
} 
public static void main(String[] args) {  
    new MyCartoon(); 
} 

所以,你可以看到,有几乎在所有的第1和第2的代码之间没有区别。 (注意: - 编译器增加了一个super调用作为第一条语句,你有充分的构造函数,如果你没有自己的superthis呼叫执行)

在上面的代码中会发生什么事是 - 编译器增加了一个默认的构造函数,然后在构造函数中移动您在位置完成的所有实例变量初始化。 如果您已经给出了多个构造函数(在这种情况下,编译器将不提供默认的构造函数),那么编译器会将instance variable初始化代码移动到每个构造函数中。

+0

+1尼斯的答案! –

+0

很好的解释。简短而准确。谢谢! – Eunkai

+0

@refusetocompile。欢迎您:) –

相关问题