簡體   English   中英

我們可以在Java中使用構造函數的返回類型嗎?

[英]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可以聲明一個方法,該方法與classclass的字段,成員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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM