Java インターフェースで静的メソッドを定義できないのはなぜですか?
-
21-08-2019 - |
質問
編集: Java 8 以降、インターフェイスで静的メソッドが許可されるようになりました。
以下に例を示します。
public interface IXMLizable<T>
{
static T newInstanceFromXML(Element e);
Element toXMLElement();
}
もちろん、これではうまくいきません。しかし、なぜそうではないのでしょうか?
考えられる問題の 1 つは、次の呼び出しを行ったときに何が起こるかということです。
IXMLizable.newInstanceFromXML(e);
この場合、空のメソッドを呼び出すだけでよいと思います(つまり、{})。すべてのサブクラスは静的メソッドの実装を強制されるため、静的メソッドを呼び出すときはすべて問題ありません。では、なぜこれが不可能なのでしょうか?
編集: 私は「Java はそういうものだから」よりも深い答えを探しているのだと思います。
静的メソッドを上書きできない特別な技術的な理由はありますか?つまり、なぜ Java の設計者は、静的メソッドではなくインスタンス メソッドをオーバーライド可能にすることにしたのでしょうか?
編集: 私の設計の問題は、インターフェイスを使用してコーディング規約を強制しようとしていることです。
つまり、インターフェイスの目的は 2 つあります。
IXMLizable インターフェイスを使用して、それを実装するクラスを XML 要素に変換できるようにしたいと考えています (ポリモーフィズムを使用すると正常に動作します)。
IXMLizable インターフェイスを実装するクラスの新しいインスタンスを作成したい場合、newInstanceFromXML(Element e) 静的コンストラクターがあることが常にわかります。
インターフェースにコメントを入れる以外にこれを確実にする方法はありますか?
解決
Java 8 では静的インターフェイス メソッドが許可されています
Java 8 では、インターフェイス できる 静的メソッドがあります。具体的なインスタンス メソッドを持つこともできますが、インスタンス フィールドを持つことはできません。
ここで実際に 2 つの質問があります。
- 古き良き時代には、なぜインターフェイスに静的メソッドを含めることができなかったのでしょうか?
- 静的メソッドをオーバーライドできないのはなぜですか?
インターフェースの静的メソッド
以前のバージョンでインターフェイスに静的メソッドを含めることができなかった強力な技術的理由はありませんでした。これは ポスターでうまくまとめられています 重複した質問の。静的インターフェイス メソッドは当初次のように考えられていました。 小さな言語の変更、 そして、ありました 公式提案 Java 7 に追加する必要がありましたが、それは後で行われました 予期せぬ合併症によりドロップされました。
最後に、Java 8 では、静的インターフェイス メソッドと、デフォルト実装によるオーバーライド可能なインスタンス メソッドが導入されました。ただし、インスタンス フィールドを持つことはできません。これらの機能はラムダ式サポートの一部であり、詳細については、次の記事を参照してください。 JSR 335のパートH。
静的メソッドのオーバーライド
2 番目の質問に対する答えは少し複雑です。
静的メソッドはコンパイル時に解決できます。動的ディスパッチは、コンパイラがオブジェクトの具体的な型を判断できないため、呼び出すメソッドを解決できないインスタンス メソッドの場合に意味があります。ただし、静的メソッドを呼び出すにはクラスが必要であり、そのクラスは既知であるため、 静的に—コンパイル時—動的ディスパッチは不要です。
ここで何が起こっているかを理解するには、インスタンス メソッドがどのように機能するかについての背景を少し理解する必要があります。実際の実装はかなり異なると思いますが、観察された動作を正確にモデル化するメソッド ディスパッチの概念を説明しましょう。
各クラスには、メソッドのシグネチャ (名前とパラメーターの型) を実際のコードのチャンクにマップしてメソッドを実装するハッシュ テーブルがあるとします。仮想マシンがインスタンスでメソッドを呼び出そうとすると、そのクラスのオブジェクトをクエリし、クラスのテーブルで要求された署名を検索します。メソッド本体が見つかると、それが呼び出されます。それ以外の場合は、クラスの親クラスが取得され、そこで検索が繰り返されます。これは、メソッドが見つかるか、親クラスがなくなるまで続きます。その結果、 NoSuchMethodError
.
スーパークラスとサブクラスの両方が同じメソッド シグネチャのテーブルにエントリを持っている場合、サブクラスのバージョンが最初に検出され、スーパークラスのバージョンは決して使用されません。これは「オーバーライド」です。
ここで、オブジェクト インスタンスをスキップして、サブクラスから始めるとします。解決は上記のように進められ、一種の「オーバーライド可能な」静的メソッドが得られます。ただし、コンパイラは実行時までそのクラスの未指定の型のオブジェクトをクエリするのを待つのではなく、既知のクラスから開始するため、解決はすべてコンパイル時に行われます。目的のバージョンを含むクラスはいつでも指定できるため、静的メソッドを「オーバーライド」することに意味はありません。
コンストラクター「インターフェース」
質問に対する最近の編集に対処するためのもう少し資料を次に示します。
の実装ごとにコンストラクターのようなメソッドを効果的に義務付けたいようですね。 IXMLizable
. 。インターフェースを使用してこれを強制しようとすることを少し忘れて、この要件を満たすクラスがいくつかあると仮定してください。どのように使用しますか?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
具体的な型に明示的に名前を付ける必要があるため、 Foo
新しいオブジェクトを「構築」するとき、コンパイラは、そのオブジェクトに必要なファクトリ メソッドが実際に存在することを検証できます。そうでない場合はどうなりますか?実装できれば IXMLizable
これには「コンストラクター」が欠けているので、インスタンスを作成してコードに渡します。 は の IXMLizable
必要なすべてのインターフェイスを備えています。
構築は実装の一部です。 インターフェースではありません。インターフェイスで正常に動作するコードは、コンストラクターを気にしません。コンストラクターを扱うコードはいずれにせよ具体的な型を知る必要があり、インターフェイスは無視できます。
他のヒント
は、これはすでにのhref = "https://stackoverflow.com/questions/129267/why-no-static-methods-in-interfaces-but-static-fields-and-inner-classes <尋ねたと答えました。 -ok / 129934#129934" >ここの
私の答えを複製します:
インタフェースでの静的メソッドを宣言するポイントはあり決してありません。彼らは)(通常の呼MyInterface.staticMethodで実行することはできません。あなたは、実装クラスMyImplementor.staticMethodを(指定することで、それらを呼び出す場合)、あなたは実際のクラスを知っている必要がありますので、インターフェースはそれが含まれているかどうかは関係ありません。
さらに重要なのは、静的メソッドをオーバーライドすることはありません、あなたがやろうとします。
MyInterface var = new MyImplementingClass();
var.staticMethod();
静的ための規則は、VARの宣言された型で定義されたメソッドが実行されなければならないことを言います。これはインタフェースであるので、これは不可能です。
あなたが実行できない理由は、「結果は= MyInterface.staticMethod()は、」それはMyInterfaceで定義されたメソッドのバージョンを実行しなければならないということです。それはインターフェイスですので、しかし、MyInterfaceで定義されたバージョンが存在することができません。これは、定義によって、コードを持っていません。
あなたは「Javaがそれそのように行いますので、」これはになると言うことができますが、実際に意思決定にも非常に良い理由のために作られた他の設計上の決定の論理的帰結である。
通常、これはFactoryパターンを使用して行われます。
public interface IXMLizableFactory<T extends IXMLizable> {
public T newInstanceFromXML(Element e);
}
public interface IXMLizable {
public Element toXMLElement();
}
の出現により、 Java 8 書くことができるようになりました デフォルト そして 静的 インターフェースのメソッド。docs.oracle/staticMethod
例えば:
public interface Arithmetic {
public int add(int a, int b);
public static int multiply(int a, int b) {
return a * b;
}
}
public class ArithmaticImplementation implements Arithmetic {
@Override
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int result = Arithmetic.multiply(2, 3);
System.out.println(result);
}
}
結果 : 6
ヒント : 静的インターフェイス メソッドの呼び出しは、クラスで実装する必要はありません。確かに、スーパークラスの静的メソッドと同じルールがインターフェイスの静的メソッドにも適用されるため、これが発生します。
静的メソッドは、サブクラスでオーバーライドすることができない、ので、彼らは抽象的なことはできませんので。そして、インタフェースのすべてのメソッドがあり、のデファクトの、抽象ます。
私はJavaインタフェースで静的メソッドを定義できないのはなぜ?
を実際にすることができますJavaの8インチの
Javaのドキュメントにあたります。
静的メソッドは、クラスに関連付けられている方法がされています それはむしろ、任意のオブジェクトよりも定義されています。クラスのすべてのインスタンス その静的メソッドを共有します。
のJava 8のインターフェイスは、ののデフォルトの方法と静的メソッドを持つことができます。私たちは私たちの図書館にヘルパーメソッドを整理するためにこれは容易になります。私たちは、むしろ別のクラスに比べて、同じインターフェイスのインターフェイスに固有の静的メソッドを維持することができます。
デフォルトのメソッドの例:
list.sort(ordering);
の代わりに
Collections.sort(list, ordering);
(自体の DOCから)静的メソッドの例:
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
インターフェースは、本質的にインスタンスではなく、クラスオブジェクトに関連付けられている多型と懸念しています。したがって、静的インタフェースのコンテキストでは意味がない。
まず、すべての言語の決定は、言語のクリエイターによってなされた決定です。静的メソッドは、インタフェースの一部にすることはできませんと言うソフトウェアエンジニアリングや言語の定義またはコンパイラ/インタプリタの書き込みの世界では何もありません。私は彼らのために言語と書かれたコンパイラのカップルを作成しました - それはすべてただ座っと意味のあるセマンティクスを定義しています。私はインターフェイスの静的メソッドのセマンティクスが著しく明確であると主張するだろう - 。コンパイラは実行時にする方法の解決を延期しなければならない場合でも、
第二に、すべての静的メソッドが含まインタフェースパターンを有するための正当な理由がある意味で、我々は静的メソッドを使用することを - 。私はあなたのいずれかのために話すことはできませんが、私は定期的に静的メソッドを使用します
最も可能性が高い正解は言語がインターフェイスの静的メソッドのために、定義された時点で、必要性が認識されたことではありません。 Javaは、長年にわたって多くのことを成長してきたし、これは明らかに、いくつかの関心を得ているアイテムです。それは、Java 7のために見たことがその言語の変化をもたらす可能性があるの関心のレベルにまで上昇していることを示しています。私はもはや単なるので、私は、サブクラスのインスタンスで静的変数にアクセスするために私の非静的getterメソッドを呼び出すことができるオブジェクトをインスタンス化する必要がないとき、私は、1のために、幸せになります...
静的メソッドはインスタンスメソッドのような仮想的ではありませんので、私は、Javaの設計者は、彼らがインタフェースでそれらをしたくなかったことを決めたとします。
しかし、あなたはインターフェース内部の静的メソッドを含むクラスを置くことができます。あなたはそれを試みることができる!
public interface Test {
static class Inner {
public static Object get() {
return 0;
}
}
}
- 「静的メソッドをオーバーライドできない特別な理由はありますか?」
定義を記入して、その質問を言い換えさせてください。
- 「コンパイル時に解決されたメソッドが実行時に解決できない特別な理由はありますか。」
または、より完全に言うと、インスタンスなしでメソッドを呼び出したいが、クラスはわかっている場合、持っていないインスタンスに基づいてメソッドを解決するにはどうすればよいですか。
コメントEDIT: As of Java 8, static methods are now allowed in interfaces.
これは、Javaの8以降の静的メソッドはインターフェイスでは、右許可されているが、あなたの例では、まだ動作しません。あなただけの静的メソッドを定義することはできません:あなたはそれを実装する必要があります。また、コンパイルエラーを取得します。
。さて、ジェネリックずに、静的インタフェースは無用です。だから、彼らのためには実際の使用はありません。
ジェネリック医薬品では、彼らが使用することを持っている - デフォルトの実装の有無にかかわらず。明らかようにオーバーライドしなければそこに必要があるだろう。しかし、私の推測では(他の答えが鈍角に指摘される)ので、努力する価値は考えられなかった、彼らは有効に実施するために必要と思い、このような使い方は非常にOOではなかったということです。
いくつかの答えは、オーバーライド静的メソッドの概念と問題を議論してきました。しかし、時には、あなたはそれはあなたが使用したいだけで何のようにそれはそうパターンに遭遇します。
例えば、Iは、値オブジェクトを有するオブジェクト・リレーショナル層で動作するだけでなく、値のオブジェクトを操作するためのコマンドを有します。様々な理由のために、各値オブジェクトクラスは、フレームワークは、コマンド・インスタンスを見つけてみましょういくつかの静的メソッドを定義しなければなりません。たとえば、あなたがしたい人を作成します:
cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();
とあなたがしたいIDで人をロードします。
cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();
これはかなり便利です、しかし、それはその問題を抱えています。特に静的メソッドの存在は、インターフェイスに強制することはできません。インタフェースでオーバーライド静的メソッドは、それが何らかの形で仕事ができる場合にのみ、我々は、必要があると思いまさになります。
EJBのホームインタフェースを持つことにより、この問題を解決します。各オブジェクトは、その家を見つける方法を知っていて、ホームは「静的」メソッドが含まれています。必要に応じて、この方法は、「静的」メソッドをオーバーライドすることができ、あなたのBeanのインスタンスには適用されないメソッドを持つ通常の(それが「リモート」と呼ばれています)インターフェイスを散らかしていません。ただ、通常のインターフェースは「getHome()」メソッドを指定します。 Homeオブジェクトのインスタンスを返します(シングルトン可能性があり、私は考えます)と、呼び出し側は、すべてのPersonオブジェクトに影響を与える操作を行うことができます。
Why can't I define a static method in a Java interface?
インタフェースのすべてのメソッドは、明示的に抽象的であり、静的メソッドは抽象することはできませんので、したがって、あなたは、静的としてそれらを定義することはできません。
インターフェースは、例えば、静的に間接参照することはできませんISomething.member
。インターフェイスは、常にインターフェイスのサブクラスのインスタンスを参照する変数を介して間接参照されます。したがって、インタフェース参照は、そのサブクラスのインスタンスなしを意味するサブクラス知ることはできません。
このように界面における静的メソッドに最も近い近似は、「この」、すなわちインスタンスの任意の非静的メンバにアクセスしない無視非静的メソッドであろう。低レベルの抽象化では、(任意のvtableの中のルックアップの後)すべての非静的メソッドは、実際に暗黙の仮パラメータとして「これを」取るクラススコープを持つだけの機能です。その概念の証拠としてにJavaを使用 Scalaのシングルトンオブジェクトとの相互運用性を参照してください。 したがって、すべての静的メソッドは、「この」パラメータを取らないクラススコープを持つ関数です。したがって、通常の静的メソッドは、スタティックにコールすることができるが、前述のように、インターフェースには実装を持たない(抽象的である)。
このように界面における静的メソッドに最も近い近似値を得るために、次に非静的インスタンスのメンバのいずれかにアクセスしない、非静的メソッドを使用することです。静的(コンパイル時に)ISomething.member()
をリンクする方法がないため、他の方法で何のパフォーマンス上の利点はないであろう。私はインターフェイスに静的メソッドの参照のみの利点は、それが入力「は、この」暗黙の(すなわち、無視する)、したがって非静的インスタンスのメンバのいずれかへのアクセスを禁止しないことです。これはアクセスしない機能は、「これは」、それを含むクラスに関しても、読み取り専用immutateではないことを暗黙的に宣言します。しかし、インタフェースISomething
で「静的」の宣言はまた、コンパイルエラーを引き起こすISomething.member()
でアクセスしようとした人々を混乱させる。私は、コンパイラエラーが十分に説明したならば、それは我々がここでやっている(と3のために繰り返されたとして、彼らは(明らかに主にファクトリメソッドを)望むものを達成するために、非静的メソッドを使用することについて人々を教育しようとするよりも良いだろうと仮定しますこのサイト上のQ&Aの時間)、それは明らかに多くの人々のための直感的ではない問題です。私は、正しい理解を得るためにしばらくそれについて考える必要がありました。
インターフェイスに変更可能な静的フィールドを取得する方法は、そのサブクラスでその静的フィールドにアクセスするために、界面に非静的ゲッターとセッターメソッドを使用することです。追記は、明らかに不変の静はstatic final
のJavaインタフェースで宣言することができます。
インターフェースは、ちょうどクラスには、静的な項目があるものである、それらのものの実際の実装ではなく、提供されるもののリストを提供します。
あなたは静をしたい場合は、抽象クラスを使用して、それを継承し、そうでない場合は、静的を削除します。
助け希望!
静的メソッドではないクラスのインスタンスへのクラスに属しているので、あなたは、インターフェイスの静的メソッドを定義することができず、インタフェースはクラスではありません。 。に
しかし、あなたがしたい場合は、あなたがこれを行うことができます:
public class A {
public static void methodX() {
}
}
public class B extends A {
public static void methodX() {
}
}
この場合、あなたが持っているもの)methodX(と呼ばれる2つの異なる静的メソッドを持つ2つのクラスです。
あなたがそれを行うこととし、この例を考えてみます:
interface Iface {
public static void thisIsTheMethod();
}
class A implements Iface {
public static void thisIsTheMethod(){
system.out.print("I'm class A");
}
}
class B extends Class A {
public static void thisIsTheMethod(){
System.out.print("I'm class B");
}
}
SomeClass {
void doStuff(Iface face) {
IFace.thisIsTheMethod();
// now what would/could/should happen here.
}
}
実施することができる何かが(代わりにインタフェースで静的メソッドの)静的なインターフェースです。与えられた静的インタフェースを実装するすべてのクラスは、対応する静的メソッドを実装する必要があります。あなたが使用して、任意のクラスclazzから静的インタフェースのSIを得ることができます。
SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null
あなたはsi.method(params)
を呼び出すことができます。
あなたが得る(またはの実装チェック)コンパイル時に未知のクラスからSI静的メソッドの実装をすることができますので、これは(例えば、工場のデザインパターンのために)有用であろう!
動的ディスパッチが必要であり、あなたは、(静的インターフェースを介して呼び出された場合)、それを拡張したクラスの静的メソッド(最終でない場合)をオーバーライドすることができます。
明らかに、これらのメソッドは、そのクラスの静的変数にのみアクセスすることができます。
、私はインターフェイスの静的メソッドを指定することができるということは役立つだろう(Javaの7を使用してにロックされた)私は現在働いているシナリオでチャイムしようと思いました。
私はヘルパーメソッドは、さまざまな理由で値を評価するとともに、「ID」と「のdisplayName」フィールドを定義したいくつかの列挙型の定義を持っています。インターフェイスを実装すると、私はgetterメソッドは、静的なヘルパーメソッドが整備されているが、いないことを保証することができます。列挙型なので、本当に方法は、列挙型自体に定義する必要がありますので継承された抽象クラスなどの何かにヘルパーメソッドをオフロードするクリーンな方法はありません。それが列挙型であるため、また、あなたが実際にインスタンス化オブジェクトとしてそれを渡すことができるとインタフェース型として扱いますが、インタフェースを介して、静的なヘルパーメソッドの存在を必要とすることができるということは、私がおよそ好きなものではありませんそれは、Java 8でサポートされます。
ここでコード私のポイントを説明するのです。
インタフェースの定義:
public interface IGenericEnum <T extends Enum<T>> {
String getId();
String getDisplayName();
//If I was using Java 8 static helper methods would go here
}
1つの列挙型の定義の例:
public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
STANDARD ("Standard", "Standard Mode"),
DEBUG ("Debug", "Debug Mode");
String id;
String displayName;
//Getter methods
public String getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
//Constructor
private ExecutionModeType(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}
//Helper methods - not enforced by Interface
public static boolean isValidId(String id) {
return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
}
public static String printIdOptions(String delimiter){
return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
}
public static String[] getIdArray(){
return GenericEnumUtility.getIdArray(ExecutionModeType.class);
}
public static ExecutionModeType getById(String id) throws NoSuchObjectException {
return GenericEnumUtility.getById(ExecutionModeType.class, id);
}
}
ジェネリック列挙ユーティリティの定義:
public class GenericEnumUtility {
public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(enumOption.getId().equals(id)) {
return true;
}
}
return false;
}
public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
String ret = "";
delimiter = delimiter == null ? " " : delimiter;
int i = 0;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(i == 0) {
ret = enumOption.getId();
} else {
ret += delimiter + enumOption.getId();
}
i++;
}
return ret;
}
public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
List<String> idValues = new ArrayList<String>();
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
idValues.add(enumOption.getId());
}
return idValues.toArray(new String[idValues.size()]);
}
@SuppressWarnings("unchecked")
public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
id = id == null ? "" : id;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(id.equals(enumOption.getId())) {
return (T)enumOption;
}
}
throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
}
}
のは、インターフェイスで許可された静的メソッドを想定してみましょう: *彼らは、そのメソッドを宣言するすべて実装するクラスを強制します。 *インタフェースは、通常のオブジェクトによって使用されるので、それらの上の唯一の効果的な方法は、非静的なものだろう。 *特定のインターフェイスを知っている任意のクラスは、その静的メソッドを呼び出すことができます。したがって、実装クラスの静的メソッドは、下に呼び出されますが、呼び出し元のクラスは知りません。どのようにそれを知っていますか?それはそれを推測する一切のインスタンスを持っていません!
インターフェースは、オブジェクトを操作するときに使用すると考えられていました。このように、オブジェクトが特定のクラスからインスタンス化されるので、この最後の問題が解決されます。呼び出しクラスは、インスタンス化は、第三のクラスによって行うことができるので、特定のクラスであるかを知る必要はありません。だから、呼び出し元のクラスは、インタフェースのみを知っています。
私たちは、これは静的メソッドに拡張することにしたい場合は、我々の前に実装したクラスをespecifyする可能性を持っている必要があります。、その後、呼び出し元のクラスへの参照を渡します。これは、インターフェイスの静的メソッドを介してクラスを使用することができます。しかし、この参照と対象物との間differenteは何ですか?私達はちょうどそれがクラスだったもの表すオブジェクトを必要とします。さて、オブジェクトは、古いクラスを表し、古い静的メソッドを含む新しいインタフェースを実装することができ - それらは現在、非静的です。
メタクラスは、この目的のために役立ちます。あなたは、JavaのクラスClassをしようとします。しかし、問題は、Javaは、このために十分に柔軟ではないということです。あなたは、インターフェイスのクラスオブジェクトのメソッドを宣言することはできません。
このメタ問題がある - あなたがお尻を行う必要があるとき、
..何とか何とか
同じロジックを持つメソッドは非静的作る -とにかく、あなたは簡単な回避策があります。しかし、その後、あなたが最初のメソッドを呼び出すためのオブジェクトを作成する必要があります。
これを解決するには: エラー:メソッド本体の欠落、または抽象宣言 静的な無効メイン(文字列[] args);
interface I
{
int x=20;
void getValue();
static void main(String[] args){};//Put curly braces
}
class InterDemo implements I
{
public void getValue()
{
System.out.println(x);
}
public static void main(String[] args)
{
InterDemo i=new InterDemo();
i.getValue();
}
}
出力: 20
今、私たちは、インターフェイスに静的メソッドを使用することができます。
私はあなたがそれらを必要としないので、Javaは静的インタフェースのメソッドを持っていないと思います。あなたは、あなたが考えるかもしれないが... どのようにそれらを使用するのでしょうか?あなたのようにそれらを呼び出したい場合は、
MyImplClass.myMethod()
あなたはインターフェイスでそれを宣言する必要はありません。あなたのようにそれらを呼び出したい場合は、
myInstance.myMethod()
それは静的ではありません。 あなたが実際に最初の方法を使用しようとしてますが、まさにそのような静的メソッドを持つように、各実装を強制したい場合、それは本当にコーディング規約ではなく、インタフェースと呼び出し元のコードを実装して、インスタンス間の契約です。
インターフェースを使用すると、インターフェイスと呼び出すコードを実装するクラスのインスタンス間の契約を定義することができます。そして、Javaは、あなたがこの契約に違反していないことを確認するのに役立ちますので、あなたがそれに頼ることができ、この契約を実装してどのようなクラス心配しないで、単に「契約を締結した誰かが」十分です。静的インタフェースの場合は、あなたのコード
MyImplClass.myMethod()
各インターフェースの実装は、このメソッドを持っているので、あなたはそれで確認するためにあなたを助けるためにJavaを必要としないという事実に依存しません。
どのようなインタフェースでの静的メソッドが必要であるあなたがインターフェイスのオブジェクト全体的なアイデアのインスタンスを作成する必要はありません場合は、静的メソッドは基本的に使用されていることはあなたから転用している静的メソッドの導入により、OOPの概念にもたらすことですコンセプトます。