簡體   English   中英

為什么構造函數不能是最終的、靜態的或抽象的?

[英]Why can't constructors be final, static, or abstract?

為什么構造函數在 Java 中不能是最終的、靜態的或抽象的?

例如,你能向我解釋為什么這是無效的嗎?

public class K {

    abstract public K() {
        // ...
    }
}

當您將方法設置為final它意味着: “我不希望任何類覆蓋它。” 但根據 Java 語言規范:

JLS 8.8 - “構造函數聲明不是成員。它們永遠不會被繼承,因此不會被隱藏或覆蓋。”

當您將方法設置為abstract方法時,這意味着: “此方法沒有主體,應該在子類中實現。” 但是在使用new關鍵字時隱式調用構造函數,因此它不能缺少主體。

當您將方法設置為static它意味着: “此方法屬於類,而不是特定對象。” 但是構造函數被隱式調用來初始化一個對象,所以使用靜態構造函數是沒有意義的。

問題實際上是為什么您希望構造函數是static or abstract or final

構造函數不是繼承的所以不能被覆蓋所以有最終構造函數有什么用

創建類的實例時會自動調用構造函數,它可以訪問類的實例字段。 靜態構造函數的用途是什么。

構造函數不能被覆蓋,所以你會用抽象構造函數做什么。

Java 構造函數是隱式final 的,其語義的靜態/非靜態方面是隱式的1 ,Java 構造函數抽象是沒有意義的。

這意味着finalstatic修飾符是多余的, abstract關鍵字根本沒有意義。

自然地,Java 設計者在任何方面都沒有看到在構造函數上允許冗余和/或無意義的訪問修飾符......所以這些是 Java 語法所不允許的。

旁白:令人遺憾的是,他們沒有對接口方法進行相同的設計調用,其中publicabstract修飾符也是多余的,但無論如何都是允許的。 也許這有一些(古老的)歷史原因。 但無論哪種方式,如果不呈現(可能)數以百萬計的現有 Java 程序不可編譯,就無法修復它。


1 - 實際上,構造函數混合了靜態和非靜態語義。 您不能在實例上“調用”構造函數,並且它們不是繼承的,也不是可覆蓋的。 這類似於靜態方法的工作方式。 另一方面,構造函數的主體可以引用this ,並調用實例方法……就像實例方法一樣。 然后是構造函數鏈,這是構造函數獨有的。 但真正的重點是這些語義是固定的,沒有必要允許冗余且可能令人困惑的static修飾符。

  • public構造函數:對象可以在任何地方創建。

  • 默認構造函數:對象只能在同一個包中創建。

  • protected構造函數:對象只能由包外的類創建,前提是它是子類。

  • private構造函數:對象只能在類內部創建(例如,在實現單例時)。

staticfinalabstract關鍵字對構造函數沒有意義,因為:

  • static成員屬於一個類,但創建對象需要構造函數。

  • abstract類是部分實現的類,其中包含要在子類中實現的抽象方法。

  • final限制修改:變量變為常量,方法不能被覆蓋,類不能被繼承。

任何構造函數都不能被聲明為最終的。 您的編譯器總是會給出“不允許修飾符 final”類型的錯誤,當應用於方法時,意味着該方法不能在子類中被覆蓋。 構造函數不是普通的方法。 (適用不同的規則)此外,構造函數永遠不會被繼承。 所以宣布它最終是沒有意義的。

最終:因為無論如何您都無法覆蓋/擴展構造函數。 您可以擴展一個類(以防止您將其設為最終)或覆蓋一個方法(以防止您將其設為最終),但對於構​​造函數而言,沒有類似的東西。

靜態:如果您查看執行,構造函數不是靜態的(它可以訪問實例字段),如果您查看調用方,它是(某種)靜態的(您在沒有實例的情況下調用它。很難想象構造函數完全靜態或非靜態並且在這兩個事物之間沒有語義分離,用修飾符區分它們是沒有意義的。

Abstract : Abstract 僅在存在覆蓋/擴展的情況下才有意義,因此與 'final' 相同的論點適用

  1. 構造函數不是普通的方法。 (適用不同的規則)
  2. 此外,構造函數永遠不會被繼承。 所以宣布它最終是沒有意義的。 任何構造函數都不能被聲明為最終的。 你的編譯器總是會給出“不允許修改器最終”類型的錯誤
  3. 檢查 JLS 第 8.8.3 節(JLS 和 API 文檔應該是您的一些主要信息來源)。

JLS 第 8 節提到了這一點。

構造函數(第 8.8 節)與 methods 類似,但不能通過方法調用直接調用; 它們用於初始化新的類實例。 與方法一樣,它們可能會被重載(第 8.8.8 節)。

但是構造函數不是常規方法。 他們不能這樣比較。

為什么構造函數不能是 static 和 final 在上面的答案中有很好的定義。

摘要:“抽象”意味着沒有實現。 並且只能通過繼承來實現。 因此,當我們擴展某個類時,除了“構造函數”之外,所有父類成員都在子類(子類)中繼承。 所以,讓我們假設,當構造函數沒有在子類中繼承時,你如何設法聲明構造函數“抽象”,而不是如何在子類中給出它的實現?

這就是為什么構造函數不能是抽象的。

讓我們看看第一個最終公共 K(){

*在修飾符final之上是restrict,因為如果它是final,那么在某些情況下,只有在其他類或同一個類中,我們才會覆蓋它,這樣就不會在這里發生,而不是final,例如:

we want public void(int i,String name){
//this code not allowed

讓 static,, static itz 所有關於類級別,但我們通過使用 'new' 關鍵字創建基於對象的構造函數 so,,,,,, thatsall

抽象 itz 最糟糕的是這里不是因為沒有任何抽象方法或任何聲明的方法

不幸的是,在 PHP 中,編譯器不會對abstract構造函數和final構造函數提出任何問題。

<?php

abstract class AbstractClass 
{
   public abstract function __construct();
}

class NormalClass 
{
    public final function __construct() {
        echo "Final constructor in a normal class!";
    }
}

在 PHP 中不允許使用static構造函數,並且會引發fatal異常。

顯然,在AbstractClass構造函數可以聲明為抽象加上未實現,也可以聲明為finalpublicprivateprotected )加上函數體

關於 PHP 的其他一些相關事實:

  1. 在 PHP 中有多個構造函數__construct()是不可能的。
  2. 在 PHP 中,構造函數__construct()可以聲明為abstractfinalpublicprivateprotected

這段代碼經過測試,在 PHP 5.6 到 7.4 版本中都適用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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