7

私はインターフェースAを持っており、そのためにいくつかの異なる実装を提供する必要があります。ただし、これらの実装はいくつかのヘルパーメソッドを共有しているため、これらのメソッドを抽象基本クラスに移動しました。

Interface A {
    void doX();
}

abstract Class B implements A {
    protected void commonY() {
        // ...
    }

    @Override
    public abstract void doX();
}

Class C extends B {
    @Override
    public void doX() {
        // ...
    }
}

Class D extends B {
    @Override
    public void doX() {
        // ...
    }
}

私のコードは期待どおりに機能しますが、いくつか質問があります。

  • クラスBで抽象メソッドdoX()を宣言する必要がありますか?なぜだめですか)?

  • クラスCとDで「実装A」も明示的に宣言する必要がありますか?なぜだめですか)?

4

6 に答える 6

8

私はそれを次のように行う方が良いと思います:

Interface A {
        void doX();
}

abstract Class B {
        protected void commonY() {
                // ...
        }
}

Class C extends B implements A{

        public void doX() {
                // ...
        }
}

Class D extends B implements A{

        public void doX() {
                // ...
        }
}

インターフェイス(メソッドのシグネチャ)と実装を混在させないでください。

于 2008-12-09T11:47:21.883 に答える
4
  • クラスBで抽象メソッドdoX()を宣言する必要がありますか?なぜだめですか)?

いいえ。これは抽象クラスです。インターフェースを定義すると、すべてのサブクラスがこれらのメソッドを実装する必要があります。言い換えれば、それは冗長です。

  • クラスCとDで「実装A」も明示的に宣言する必要がありますか?なぜだめですか)?

いいえ、繰り返しますが、スーパークラス(抽象基本クラス)がそのインターフェイスを実装しているため、具象サブクラスはそのインターフェイスを実装することが保証されます。

于 2008-12-09T11:44:55.630 に答える
1

I'll just throw in the other option.

Turn abstract class B into an AUtil class that doesn't implement A. The method signatures may require an additional argument of type A to work with.

C and D implement A, and instantiate an AUtil internally. This does allow C and D to extend other classes.

于 2008-12-09T12:00:04.167 に答える
1

JeeBee に同意します。ヘルパー メソッドを抽象基本クラス以外の場所に実装することを検討してください。

ヘルパー メソッド commonY() が抽象基本クラス B にのみ存在する場合、Interface A を実装するすべてのクラスは、commonY() の実装を利用するために、基本クラス B も拡張する必要があります。ただし、クラス B の拡張を常に強制されるとは限りません。

また、将来的に commonY() の実装を変更したい場合はどうしますか? その後、インターフェース A の多くの実装に影響を与えます。しかし、インターフェース A のこれらすべての実装を制御しないと、意図せずにそれらの機能に (悪い意味で) 影響を与える可能性があります。

この状況で抽象基本クラスを使用すると、見返りが得られずに柔軟性が失われる可能性があります。

于 2008-12-09T22:04:07.597 に答える
0

インターフェイスを実装する抽象クラスは、そのインターフェイスを実装する必要があります。具体的には、そのインターフェイスで指定されたすべてのメソッド名とシグネチャに対してパブリックメソッドが必要です。

継承は推移的です。クラスCがインターフェイスAを実装するクラスBを派生させる場合は、クラスCがインターフェイスAを実装するように記述する必要はありません。ただし、それほど害はありません。

于 2008-12-09T11:45:03.917 に答える
0

私は宣言doX()したり、「 」をB追加したりしません。繰り返してはいけないからです。implements ACD

の要約doX()B、「」ですでに指定されているため、何も追加しませんimplements A。とに「 implements A」を追加する場合も同様です。CD

Cこれらの句の唯一の可能な使用法はドキュメントです。 (またはD)が-aであることを非常に明示的にしたい場合Aは、を追加できますがimplements、コンパイラにとっては実際には重要ではないことに注意してください。

于 2008-12-09T11:46:02.760 に答える