2

Javaで次のシナリオを想定しましょう

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
}

Baz.bar()静的にできないのはなぜですか?

これを行うと、コンパイラ エラーが発生します注釈をThis static method cannot hide the instance method from Foo追加すると、コンパイラ エラーが@OverrideBaz.bar()The method bar() of type Baz must override or implement a supertype method

interface を使用する人の観点からは、インスタンス化せずにクラスを明示的に使用しているすべての人が静的実装を持つメソッドを利用できるようにしながらFoo、実装クラスは依然としてインターフェイス要件を満たしているように思えます。BazBaz

コンパイラがこのシナリオを許可しないのはなぜですか?

編集

十分に明確ではなかったかもしれませんが、実際に尋ねているのは、なぜこれが許可されていないのかということです。私の観点からは、インターフェイス定義のメソッドの可視性を低下させているわけではないからです。

はい、質問ではなくタイトルで抽象という言葉を使用したことは知っていますが、それはabstractキーワードがインターフェースで暗示されているためです。

編集2

なぜ私がこれを求めているのかを明確にするために、より現実に近い例を追加します。

public interface DatabaseMapper<T extends DatabaseType> {
    Entry<T> convert(Entry);
}

public interface SQL extends DatabaseType {}

public class SQLEntry implements Entry<SQL> {}

public class SQLMapper implements DatabaseMapper<SQL> {
    public SQLEntry convert(Entry e) {
        //Convert some generic entry to the SQLEntry type
    }
}

Mapperこの場合、すべての実装にメソッドを実装するように強制したいのですconvertが、同時に、このメソッドはオブジェクトの内部状態にまったく依存しない可能性があり、ジェネリックをSQLMapperに変換できることが望ましい場合があります。おそらくデータベース接続文字列などをEntry含むSQLEntryインスタンス化プロセスを経ずに。

これが私が直面したシナリオであり、同じ方法でこれを達成できない理由を誰かが知っているかどうかを確認したかった理由です。たとえばpublic static SQLEntry convertStatic(Entry e)、オーバーライドされたメソッドが実装を委譲する に頼る必要がないなどです。

繰り返しますが、コンパイラの仕組みが原因で Java ではこれが不可能であることを理解しています。

4

3 に答える 3

3

本当の答えは、Java がこのように定義されていないということです。他の言語では、これは可能です。

たとえば、Scala には静的メソッドはありませんが、代わりにobjectシングルトンであり、これを可能にする静的メソッドを定義できます。Smalltalk や Ruby のような動的言語では、クラスはオブジェクトのようなものであり、これも可能です。

しかし Java では、静的メソッドはグローバル メソッドに似ています。オブジェクトにバインドされていないため、静的メソッドselfにもの概念はありません。super結果として、継承/オーバーライドは実際には適用されません。

継承の概念がなければ、abstract.

于 2012-11-15T15:27:53.220 に答える
1

抽象メソッドは、サブクラス メソッドによってオーバーライド (定義) されることになっています。静的メソッドはインスタンスに関連するのではなく、定義されている特定のクラスに関連するため、オーバーライドできません。

たとえば、非静的メソッドは次のように使用されます。

Foo b = new Baz();
Object result = b.bar();

static は次のように使用されます。

Object result = Baz.bar2();

バーを静的にしてインスタンスレベルでオーバーライドしたい場合は、次のようにします。

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    @Override
    public Object bar() {
          return Baz.bar2();
    }
    public static Object bar2() {
     //your implementation
    }

}
于 2012-11-15T15:20:18.077 に答える
1
public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
 public static  Object bar() {
        //My implementation
    }
}

メソッドのシグネチャが同じであるため、 bar () はオーバーロードされていません。抽象クラスで非静的 bar() を宣言したため、このクラスでそのメソッドを実装する必要があります。

于 2012-11-15T15:20:52.813 に答える