[英]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.