[英]Can we have a return type for a constructor in Java?
以下代码给出了编译错误:
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{}
我已经读过构造函数不应该有返回类型,这显然不是一直都是正确的。 所以我的问题是我们什么时候应该有构造函数的返回类型?
在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();
}
}
构造函数不能具有返回类型。 根据定义,如果方法具有返回类型,则它不是构造函数。
JLS 8.8构造函数声明
构造函数用于创建作为类实例的对象。 [名称必须与类名匹配,但是]在所有其他方面,构造函数声明看起来就像没有结果类型的方法声明。
以下代码段确实给出了编译错误:
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
提供任何构造函数,所以编译器会自动为您创建默认构造函数。 然而,这个默认的构造函数试图调用父类的默认构造函数Parent
, 不具有默认构造函数。 THAT'S FO的编译错误的源。
这是默认构造函数的规范:
JLS 8.8.9默认构造函数
如果类不包含构造函数声明,则会自动提供不带参数的默认构造函数 :
- 如果声明的类是原始类
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方法声明
class
可以声明一个方法,该方法与class
或class
的字段,成员class
或成员interface
具有相同的名称, 但是不鼓励这样做 。
你会发现如果你创建一个new Parent()
或一个new Child()
, "Yipppee!!!"
不会打印到标准输出。 该方法在创建时不会被调用,因为它不是构造函数。
隐式超级构造函数parent()未定义为默认构造函数。 必须定义一个显式构造函数
将来首先阅读错误消息,然后尝试推理(或找到)它所暗示的含义。
构造函数没有返回类型。 调用构造函数来创建该类型的实例。 基本上从构造函数“返回”的是该类型的实例,可以使用。
构造函数没有任何返回类型
尝试将其更改为:
class parent
{
parent(int a){}
}
class child extends parent
{
child(int a){
super(a);
}
}
从技术上讲,您没有向构造函数添加返回类型,而是将构造函数更改为恰好与该类名称相同的方法。 你应该做的是调用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
参数。
已经回答了codaddict但有两条评论。 通过java代码约定类应该以大写字母开头(它也很有助于添加修饰符)。 如果你有编译错误然后把它,这里的所有困难的情况都很明显没有它。
构造函数没有返回类型。构造函数返回类型的实例.Constructor应该与类的名称相同。
你通过添加int所做的就是将“构造函数”转换为具有默认可见性的方法,然后因为你没有指定构造函数,它只会在编译时为你添加一个默认构造函数。
如果要编译它,则必须指定一个默认构造函数,这是Child类正在查找的内容,例如:
class parent
{
parent(int a){}
parent(){}
}
class child extends parent{}
1)最佳做法是使用大写字母开始类,使用较低的大小写字母开始方法。
2)如果没有为类创建构造函数,它有一个默认的空构造函数。
3)从类继承时,您需要至少覆盖其中一个构造函数,如果不指定任何构造函数,则自动继承空构造函数。
如果子进程调用super(int i)
,如果父类没有构造函数(那么它将具有默认的空构造函数)或者父类专门实现了空构造函数,那么您提交的代码将起作用。
这会奏效。
public class Parent {
public Parent(int i) { }
public Parent() { }
}
public class Child {
}
空的Child类的行为就像它是这样编写的:
public class Child {
public Child() {
super();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.