我们可以在Java中使用构造函数的返回类型吗?

时间:2010-08-17 11:03:24

标签: java constructor

以下代码给出了编译错误:

class parent {
  parent(int a){}
}

class child extends parent{}

错误:

Main.java:6: cannot find symbol
symbol  : constructor parent()
location: class parent
class child extends parent{}
^
1 error

我试图做不同的事情,发现在父构造函数中添加一个返回类型可以摆脱错误!!!

class parent {
  int parent(int a){}
}

class child extends parent{}

我已经读过构造函数不应该有返回类型,这显然不是一直都是正确的。所以我的问题是我们什么时候应该有构造函数的返回类型?

11 个答案:

答案 0 :(得分:29)

case 1 中,子类没有任何构造函数,因此编译器会为您添加一个默认构造函数,并且还会添加对超类构造函数的调用。所以你的孩子班有效地看起来像:

class child extends parent {
 child() {
  super();
 }
}

调用super()在基类中查找零参数构造函数,因为没有这样的构造函数可以得到错误。

案例2 中,父父类没有任何构造函数

int parent(int x) {} 不是构造函数,因为它具有返回类型。它只是一个具有类名的方法。子类也没有任何构造函数。因此编译器为child和parent添加了默认构造函数,并且还添加了对超类构造函数的调用:

class parent {
 parent() {
  super(); // calls Object class ctor.
 }
  int parent(int x) {} // not a ctor.
}

class child extends parent {
 child() {
  super();
 }
}

答案 1 :(得分:18)

在没有返回类型的构造函数

构造函数不能具有返回类型。根据定义,如果方法具有返回类型,则它不是构造函数。

  

JLS 8.8 Constructor Declarations

     

构造函数用于创建作为类实例的对象。 [名称必须与类名匹配,但是]在所有其他方面,构造函数声明看起来就像没有结果类型的方法声明。


在默认构造函数

以下代码段确实会出现编译错误:

class Parent {
   Parent(int a){}
}

class Child extends Parent{

   // DOES NOT COMPILE!!
   // Implicit super constructor parent() is undefined for default constructor.
   // Must define an explicit constructor

}

原因不是因为构造函数中的返回类型,而是因为您没有为Child提供 ANY 构造函数,所以默认构造函数是由编译器自动为您创建。但是,此默认构造函数尝试调用超类Parent的默认构造函数, NOT 具有默认构造函数。 那是编译错误的来源。

这是默认构造函数的规范:

  

JLS 8.8.9 Default Constructor

     

如果某个类不包含构造函数声明,则会自动提供不带参数的默认构造函数

     
      
  • 如果声明的类是原始类Object,则默认构造函数为空体。
  •   
  • 否则,默认构造函数不接受任何参数,只调用不带参数的超类构造函数。
  •   

以下是一个简单的修复:

class Parent {
   Parent(int a){}
}

class Child extends Parent{

   // compiles fine!
   Child() {
      super(42);
   }

}

与构造函数具有相同名称的方法

以下代码段 DOES 编译:

// COMPILES FINE!!

class Parent  {

   // method has same name as class, but not a constructor
   int Parent(int a) {
      System.out.println("Yipppee!!!");
      return 42;
   }

   // no explicit constructor, so default constructor is provided
}

class Child extends Parent {

   // no explicit constructor, so default constructor is provided

}

实际上在上面的代码片段中没有明确的构造函数。你拥有的是一个与类同名的常规方法。这是允许的,但不鼓励:

  

JLS 8.4 Method Declarations

     

class可以声明与class具有相同名称的方法或类的成员class或成员interface不鼓励作为一种风格

您会发现,如果您创建new Parent()new Child()"Yipppee!!!" NOT 打印到标准输出。该方法在创建时不会被调用,因为它不是构造函数。

答案 2 :(得分:4)

  • 当你扩展一个没有默认构造函数的类时,你必须提供一个调用该超构造函数的构造函数 - 这就是编译错误的原因,即:
  

默认构造函数未定义隐式超级构造函数parent()。必须定义显式构造函数

  • 当你添加一个返回类型时,它不再是一个构造函数,它是一个方法,上面的内容不适用

将来首先阅读错误消息,然后尝试推理(或找到)它所暗示的含义。

答案 3 :(得分:2)

构造函数具有返回类型。调用构造函数来创建该类型的实例。基本上从构造函数“返回”的是一个可以使用的类型的实例。

答案 4 :(得分:2)

构造函数没有任何返回类型

答案 5 :(得分:1)

尝试将其更改为:

class parent 
{
parent(int a){}
}

class child extends parent
{
  child(int a){
    super(a);
  }
}

答案 6 :(得分:1)

从技术上讲,您没有向构造函数添加返回类型,而是将构造函数更改为恰好与该类名称相同的方法。你应该做的是调用super(int),因此:

class parent 
{
parent(int a){}
}

class child extends parent{ child(int a){ super(a); } }

child的代码隐式尝试执行此操作:

class child extends parent{ child(){ super(); } }

也就是说,它试图在parent中调用零参数构造函数,这显然无法完成,因为它只有一个构造函数,它接受int参数。

答案 7 :(得分:1)

已经通过codaddict回答,但有两条评论。 通过java代码约定类应该以大写字母开头(它也很有助于添加修饰符)。 如果你有编译错误然后把它放在一起,那么在没有它的情况下这一切都很明显。

答案 8 :(得分:0)

通过添加int所做的就是将“构造函数”转换为具有默认可见性的方法,然后因为您没有指定构造函数,它只会在编译时为您添加默认构造函数。 / p>

如果要编译它,则必须指定一个默认构造函数,这是Child类正在查找的内容,例如:

  class parent 
    {
      parent(int a){}

      parent(){}
    }

class child extends parent{}

答案 9 :(得分:0)

1)最佳做法是使用大写字母开始类,使用较低的大小写字母开始方法。

2)如果没有为类创建构造函数,它有一个默认的空构造函数。

3)从类继承时,您需要至少覆盖​​其中一个构造函数,如果不指定任何构造函数,则自动继承空构造函数。

如果子类有一个构造函数调用super(int i),如果父类没有构造函数(那么它将具有默认的空构造函数)或者父类专门实现了空构造函数,那么您提交的代码将起作用。 / p>

这样可行。

public class Parent {
    public Parent(int i) { }
    public Parent() { }
}

public class Child {
}

空的Child类的行为就像它是这样写的:

public class Child {
    public Child() {
        super();
    }
}

答案 10 :(得分:0)

构造函数没有返回类型。构造函数返回类型的实例.Constructor应该与类的名称相同。