web-dev-qa-db-ja.com

コンストラクターが最終的なものになれない理由

Javaでコンストラクターを最終、静的、または抽象化できないのはなぜですか?

たとえば、なぜこれが有効ではないのか説明してもらえますか?

public class K {

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

メソッドをfinalに設定すると、次のことを意味します: "クラスをオーバーライドしたくない。"しかし、Java言語仕様:

JLS 8.8 -「コンストラクター宣言はメンバーではありません。継承されることはないため、非表示またはオーバーライドの対象にはなりません。」

メソッドをabstractに設定すると、次のことを意味します: "このメソッドにはボディがなく、子クラスに実装する必要があります。"しかし、newキーワードが使用されている場合、コンストラクターは暗黙的に呼び出されるため、本体が不足することはありません。

メソッドをstaticとして設定すると、次のことを意味します: "このメソッドは特定のオブジェクトではなくクラスに属します。"しかし、コンストラクターはオブジェクトを初期化するために暗黙的に呼び出されるので、静的コンストラクターを持つ目的はありません。

155
user1232256

問題は、コンストラクタをstatic or abstract or finalにする理由です。

コンストラクターは継承されないため、オーバーライドできないため、最終的なコンストラクターを使用するにはどうすればよいですか

コンストラクターは、クラスのインスタンスが作成されると自動的に呼び出され、クラスのインスタンスフィールドにアクセスできます。静的コンストラクターの使用はどうなりますか。

コンストラクターをオーバーライドすることはできませんので、抽象コンストラクターで何をしますか。

39
RanRag

Javaコンストラクタは暗黙的 finalであり、そのセマンティクスの静的/非静的な側面は暗黙的1、およびJavaコンストラクターが抽象的である場合は無意味.

つまり、finalおよびstatic修飾子は冗長であり、abstractキーワードはまったく意味を持ちません。

当然、Javaデザイナーは、コンストラクターで冗長および/または無意味なアクセス修飾子を許可することについて、いかなる点でも見ませんでした。したがって、これらはJava文法では許可されません。

余談:public修飾子とabstract修飾子も冗長であるインターフェースメソッドに対して同じ設計呼び出しを行わなかったのは残念ですが、とにかく許可されています。おそらく、これにはいくつかの(古代の)歴史的な理由があります。しかし、どちらにしても、(おそらく)数百万の既存のJavaプログラムをコンパイル不能にしないと修正できません。


1-実際には、コンストラクターには静的セマンティクスと非静的セマンティクスが混在しています。インスタンスのコンストラクターを「呼び出す」ことはできません。コンストラクターは継承されないか、オーバーライドできません。これは、静的メソッドの動作に似ています。一方、コンストラクターの本体はthisを参照し、インスタンスメソッドのようにインスタンスメソッドを呼び出すことができます。そして、コンストラクターに固有のコンストラクターチェーンがあります。しかし、実際のポイントは、これらのセマンティクスが固定されていることであり、冗長でおそらく混乱を招くstatic修飾子を許可するポイントはありません。

14
Stephen C
  • public constructor:オブジェクトはどこでも作成できます。

  • デフォルトのコンストラクター:オブジェクトは同じパッケージ内でのみ作成できます。

  • protected constructor:オブジェクトは、パッケージがサブクラスである場合にのみ、パッケージ外のクラスによって作成できます。

  • private constructor:オブジェクトはクラス内でのみ作成できます(シングルトンを実装する場合など)。

staticfinal、およびabstractキーワードは、コンストラクターにとって意味がありません。理由は次のとおりです。

  • staticメンバーはクラスに属しますが、オブジェクトを作成するにはコンストラクターが必要です。

  • abstractクラスは部分的に実装されたクラスで、子クラスに実装される抽象メソッドが含まれます。

  • finalは変更を制限します。変数は定数になり、メソッドはオーバーライドできず、クラスは継承できません。

9
mahesh

コンストラクターを最終として宣言することはできません。コンパイラーは、「modifier final not allowed」型のエラーを常にメソッドに適用すると、メソッドがサブクラスでオーバーライドできないことを意味します。コンストラクタは通常のメソッドではありません。 (異なるルールが適用されます)さらに、コンストラクターは決して継承されません。したがって、最終的な宣言には意味がありません。

6
Jimit Rupani

最終:とにかくコンストラクタを上書き/拡張できないため。クラスを拡張する(最終にすることを防ぐ)か、メソッドを上書きする(最終にすることを防ぐ)ことができますが、コンストラクタにはこのようなものはありません。

静的:実行を見ると、コンストラクターは静的ではありません(インスタンスフィールドにアクセスできます)、呼び出し側を見ると、それは(一種)静的です(インスタンスを持たずに呼び出します) 。コンストラクターが完全に静的であるか静的でないかを想像するのは困難であり、これら2つのものを意味的に分離することなく、修飾子でそれらを区別することは意味がありません。

Abstract:Abstractは、上書き/拡張がある場合にのみ意味を持つため、「final」と同じ引数が適用されます

6
Jens Schauder
  1. コンストラクタは通常のメソッドではありません。 (異なるルールが適用されます)
  2. さらに、コンストラクターは決して継承されません。したがって、最終的な宣言には意味がありません。 コンストラクタは決してfinalと宣言できません。コンパイラは常に「modifer final not allowed」タイプのエラーを返します
  3. JLSセクション8.8.3を確認してください(JLSおよびAPIドキュメントは、主要な情報源の一部である必要があります)。
3
jaskirat Singh

JLS セクション8 はこれに言及しています。

コンストラクター(8.8)はメソッドに似ていますが、メソッド呼び出しで直接呼び出すことはできません。これらは、新しいクラスインスタンスを初期化するために使用されます。メソッドと同様に、それらはオーバーロードされる場合があります(§8.8.8)。

ただし、コンストラクターは通常のメソッドではありません。それらを比較することはできません。

2
Oh Chin Boon

コンストラクターが静的で最終的なものにできない理由は、上記の回答で明確に定義されています。

要約:「抽象」とは、実装がないことを意味します。また、継承を介してのみ実装できます。したがって、クラスを拡張すると、「コンストラクター」を除くすべての親クラスメンバーがサブクラス(子クラス)に継承されます。コンストラクタが子クラスで継承されない場合、サブクラスで実装をどのように与えることができるかよりも、コンストラクタ「Abstract」をどのように宣言するのでしょうか?

そのため、コンストラクターをabstractにすることはできません。

1
Muneeb Nasir

最初の最終公開K(){

*最後の修飾子は制限されます '最終的な場合は、他のクラスまたは同じクラスでのみオーバーライドするため、ここでは最終的には最終的には発生しません:

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

static、static itzをクラスレベルについてすべて説明しますが、 'new'キーワードを使用してオブジェクトベースのコンストラクタを作成しますso , thatsall

抽象メソッドまたは宣言されたメソッドがないため、ここではない最悪の抽象

0
veeresh kalyan