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

余生长醉 提交于 2019-12-20 12:35:40

问题


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?


回答1:


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.


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 ANY constructor for Child, a default constructor is automatically created for you by the compiler. However, this default constructor tries to invoke the default constructor of the superclass Parent, which does NOT have a default constructor. THAT'S the source fo the compilation error.

Here's the specification for the default constructor:

JLS 8.8.9 Default Constructor

If a class contains no constructor declarations, then a default constructor that 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.

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 DOES compile:

// 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 class can declare a method with the same name as the class or a field, member class or member interface of the class, but this is discouraged as a matter of style.

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




回答2:


In case 1 the 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:

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.

In case 2 parent parent class does not have any constructor

int parent(int x) {} is not a 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:

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

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



回答3:


  • 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

  • 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.




回答4:


Constructors do not have 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.




回答5:


constructors dont have any return type




回答6:


try changing it to:

class parent 
{
parent(int a){}
}

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



回答7:


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:

class parent 
{
parent(int a){}
}

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

Your code for child implicitly tries to do this:

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 int argument.




回答8:


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.




回答9:


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.

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:

  class parent 
    {
      parent(int a){}

      parent(){}
    }

class child extends parent{}



回答10:


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

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

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.

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.

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:

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



回答11:


Constructors does not have a return type.Constructor returns an instance of the type.Constructor should have the same name as that of the class.



来源:https://stackoverflow.com/questions/3501680/can-we-have-a-return-type-for-a-constructor-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!