我们可以为 Java 中的构造函数提供返回类型吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3501680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:08:13  来源:igfitidea点击:

Can we have a return type for a constructor in Java?

javaconstructor

提问by user421814

The following code gives a compilation error:

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

class parent {
  parent(int a){}
}

class child extends parent{}

Error:

错误:

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

I was trying to do different things and found that adding a return type to the parent constructor got rid of the error!!!

我试图做不同的事情,发现向父构造函数添加返回类型摆脱了错误!!!

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

class child extends parent{}

I've read that constructors should not have return type, which clearly is not correct all the times. So my question is when should we have return type for constructor?

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

回答by codaddict

In case 1the child class does not have any constructor so the compiler adds a default constructor for you and also adds a call to superclass constructor. So your child class effectively looks like:

在第1 种情况下,子类没有任何构造函数,因此编译器为您添加了一个默认构造函数,并添加了对超类构造函数的调用。所以你的孩子类实际上看起来像:

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

the call super()looks for a zero argument constructor in the base class, since there is no such constructor you get the error.

该调用super()在基类中查找零参数构造函数,因为没有这样的构造函数,您会收到错误消息。

In case 2parent parent class does not have any constructor

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

int parent(int x) {}is nota constructor as it has a return type. Its just a method which has the class name. The child class does not have any constructor as well. So the compiler adds default constructor for both child and parent and also adds call to super class constructor:

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

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

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

回答by polygenelubricants

On constructor not having return type

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

Constructor must not have a return type. By definition, if a method has a return type, it's not a constructor.

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

JLS 8.8 Constructor Declarations

A constructor is used in the creation of an object that is an instance of a class. [The name must match the class name, but], in all other respects, the constructor declaration looks just like a method declaration that has no result type.

JLS 8.8 构造函数声明

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



On default constructors

在默认构造函数上

The following snippet does give a compilation error:

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

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

}

The reason is not because of a return type in a constructor, but because since you did not provide ANYconstructor for Child, a defaultconstructor is automatically created for you by the compiler. However, this default constructor tries to invoke the default constructor of the superclass Parent, which does NOThave a default constructor. THAT'Sthe source fo the compilation error.

原因不是因为构造函数中的返回类型,而是因为您没有为 提供任何构造函数Child,编译器会自动为您创建默认构造函数。然而,这个默认的构造函数试图调用父类的默认构造函数Parent,它确实具有默认构造函数。THAT'SFO的编译错误的源。

Here's the specification for the default constructor:

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

JLS 8.8.9 Default Constructor

If a class contains no constructor declarations, then a default constructorthat takes no parameters is automatically provided:

  • If the class being declared is the primordial class Object, then the default constructor has an empty body.
  • Otherwise, the default constructor takes no parameters and simply invokes the superclass constructor with no arguments.

JLS 8.8.9 默认构造函数

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

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

The following is a simple fix:

下面是一个简单的修复:

class Parent {
   Parent(int a){}
}

class Child extends Parent{

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

}


On methods having the same name as the constructor

关于与构造函数同名的方法

The following snippet DOEScompile:

下面的代码片段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

}

There is in fact no explicit constructor in the above snippet. What you have is a regular method that has the same name as the class. This is allowed, but discouraged:

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

JLS 8.4 Method Declarations

A classcan declare a method with the same name as the classor a field, member classor member interfaceof the class, but this is discouraged as a matter of style.

JLS 8.4 方法声明

Aclass可以声明与class或 字段、成员classinterface类成员同名的方法,但出于风格的考虑,不鼓励这样做

You will find that if you create a new Parent()or a new Child(), "Yipppee!!!"will NOTbe printed to standard output. The method is not invoked upon creation since it's not a constructor.

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

回答by Bozho

  • when you extend a class that does not have a default constructor, you must provide a constructor that calls that superconstructor - that's why the compilation error, which is:
  • 当您扩展一个没有默认构造函数的类时,您必须提供一个调用该超构造函数的构造函数 - 这就是编译错误的原因,即:

Implicit super constructor parent() is undefined for default constructor. Must define an explicit constructor

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

  • when you add a return type this is no longer a constructor, it's a method, and the above does not apply
  • 当您添加返回类型时,这不再是构造函数,而是方法,并且上述内容不适用

In the future read the error messages first, and try to reason (or find) what it implies.

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

回答by Noel M

Constructors do nothave a return type. Constructors are called to create an instance of the type. Essentially what is "returned" from a constructor is an instance of that type ready for use.

构造函数没有返回类型。调用构造函数来创建类型的实例。本质上,从构造函数“返回”的是准备使用的该类型的实例。

回答by Vipul

constructors dont have any return type

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

回答by roni

Already answered by codaddict but two comments. By the java code convention classes should start with upper case (it also helful to add the modifier). If you have compilation error then put it, all tough the case here was clear without it.

已经由 codacci 回答,但有两条评论。根据 java 代码约定,类应该以大写开头(添加修饰符也很有帮助)。如果你有编译错误,那么就把它写出来,如果没有它,这里的情况就很清楚了。

回答by gustafc

Technically, you didn't add a return type to the constructor, but changed the constructor into a method which just happened to be of the same name as the class. What you should have done was calling super(int), thus:

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

class parent 
{
parent(int a){}
}

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

Your code for childimplicitly tries to do this:

您的代码child隐式尝试这样做:

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

That is, it tries to call a zero-argument constructor in parent, which obviously can't be done as it only has one constructor, which takes an intargument.

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

回答by user236682

try changing it to:

尝试将其更改为:

class parent 
{
parent(int a){}
}

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

回答by Richard

All you have done by adding the int is to turn the "constructor" into a method that has default visibility and then because you haven't specified a constructor, it will just add a default constructor for you at compilation time.

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

If you want this to compile, you will have to specify a default constructor, which is what the Child class is looking for, such as:

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

  class parent 
    {
      parent(int a){}

      parent(){}
    }

class child extends parent{}

回答by Tormod

1) It is best practice to start classes with a capital letter, and methods with a lowr case letter.

1) 最好的做法是用大写字母开头类,用小写字母开头方法。

2) When you do not create a Constructor for a class, it has a default empty constructor.

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

3) When inheriting from a class you need to override at least one of it's constructors, and if you do not specify any, you automatically inherit the empty constructor.

3)当从一个类继承时,你需要至少覆盖​​它的一个构造函数,如果你没有指定任何一个,你会自动继承空的构造函数。

The code you submitted would work if child had a constructor calling super(int i), if the parent class had no constructor (then it would have the default empty constructor) or if the parent class specifically implemented the empty constructor.

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

This will work.

这将起作用。

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

public class Child {
}

The empty Child class behaves as if it was written like this:

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

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