3

すべてのクラスが新しいフィールドを追加してスーパークラスを拡張する継承チェーンがあり、そのチェーンのすべてのクラスでtoString()メソッドを次のようにオーバーライドするとします。

public String toString()
{
    return super.toString() + "[newfield=" + newfield + "]";
}

抽象基本クラスを使用すると、継承チェーンのクラスが抽象メソッドを実装することによって具象になると、その時点からのすべてのサブクラスも、既に実装されているメソッドを継承することによって具象になります。

継承チェーンの上位に既に実装されているにもかかわらず、すべてのクラスに抽象メソッドを強制的にオーバーライド (再実装) させる方法は Java にありますか?

4

2 に答える 2

3

短い答え:いいえ。

長い答え: クラスパスをスキャンし (そのためにリフレクションのようなライブラリを使用)、抽象クラスのすべてのサブクラスをロードし、リフレクションを使用してメソッドをチェックする単体テストを作成できます。しかし、コンパイル時にそれを行う方法はありません。

Java とは別に、 AspectJにはhasMethod()ポイントカットがあり、チェックを行うことができますが、残念ながらそれはdeclare parentsアドバイスに対してのみ有効です。おそらく、aspectj を使用して 2 つのステップでそれを行うことができます。

  • インターフェイスを定義しますIllBehaved
  • 基本クラスから拡張されているがメンバーを持たないクラスにこのインターフェースを割り当てるアドバイスを定義する
  • 次に、このインターフェイスを実装するすべての型に対してコンパイル エラーを宣言します。

    pointcut isSubTypeOfYourClass(): within(com.your.BaseClass+);
    pointcut overridesMethod(): hasmethod(public void yourMethodName(..));
    declare parents: isSubTypeOfYourClass() && !overridesMethod()
                     implements com.yourcompany.IllBehaved;
    declare error: isSubTypeOfYourClass() && within(com.yourcompany.IllBehaved+):
                     "Implementation class must override <Foo> method";
    

-XhasMember私はこれをテストしていませんが、オプションをオンにすると動作するはずです。また、Maven、Ant、Eclipse などの標準ツールを使用する場合、aspectj をビルドに統合するのは簡単です。

于 2012-04-24T13:09:16.583 に答える
2

いいえ。ただし、抽象スーパー クラスの代わりに、クラスにインターフェイスを実装させることはできます。クラスがインターフェイスを実装しているかどうかは、このクラスで何をしているかによって異なりますが、コンパイル時に確認できます。

于 2012-04-24T13:08:54.883 に答える