インターフェイスを直接実装するか、スーパークラスに実装させる必要がありますか?


14

違いはありますか

public class A extends AbstractB implements C
{...}

対...

public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}

どちらの場合でも、クラスAがインターフェースに準拠することになることを理解しています。2番目のケースでAbstractBは、のインターフェイスメソッドの実装を提供できますC。それが唯一の違いですか?

のインターフェイスメソッドの実装を提供したくない場合 AbstractBどのスタイルを使用する必要がありますか?どちらか一方を使用すると、何らかの「文書化」の目的が隠されますか?


3
タイトルに関する提案:インターフェースを直接実装するか、スーパークラスにそれを実行させるか
ジャンヌ・ボヤルスキー

回答:


20

AbstractB implements Cセマンティック上の場合にすべて依存します。すなわち、それがAbstractB実装するために意味的に意味がある場合C、それのために行きます。

具体例を取り上げると、意味の違いが明らかになります。

A = Dog、AbstractB = Animal、C = IBarkの場合

理にかなった選択だけが

class Dog extends Animal implements IBark{

これは意味がありません。これは、すべての動物がbarえることを意味するからです。

class Animal implements IBark{

class Aから継承するだけではない場合、他の違いが影響しAbstractBます。#1ではCを実装する必要はなく、#2ではCを実装する必要があります。


1
+1私の答えよりもはるかに明確です!
Hand-E-Food

さらに、インターフェースがあった場合、implement Heterotrophを作成するのが妥当と思わAnimalHeterotrophます。あなたが他の多くのanimalsえている動物を期待し、同じ方法でそれらを扱いBarkingAnimal extends Animal implements IBarkたいなら、別のクラスが行く方法です。
スカーフリッジ

@scarfridge実際、動物が伸びると予想してHeterotrophいますが、ご意見をお寄せいただきありがとうございます
Karthik T

2

適切な継承関係を判断する簡単な方法は、クラス自体ではなく、それらのクラスのメソッドを呼び出すコードを調べることです。コードのどこかに、AbstractB b = new A();またはのようなものがありますotherObject.addAbstractB(this);。いずれにしても、後でそのAbstractB参照を使用してさまざまなメソッド呼び出しを行います。

その状況で、次のメソッドを呼び出したいCですか?もしそうAbstractBなら、実装する必要がありますC。そうでない場合、そうすべきではありません。そのような状況がない場合は、継承を必要とせず、結合がはるかに緩やかなので、代わりに構成を使用するようにリファクタリングする必要があります。


2

これは、「隠された」文書化の目的ではありません。AbstractBとそのすべてのサブクラスをCにキャストできます。実際には3つのスタイルがあります。

public class A extends AbstractB implements C
public class AbstractB

AbstractBが論理的にCを実装していなかった場合は、これを使用します。メソッドを提供していなくても、意味を持つ可能性があります。犬を拡張するなど、AnimalはWagを実装します。すべての動物がワグするのは意味がありません。このアプローチは、実際にAbstractBが実装を提供することを妨げるものではないことに注意してください。

public class A extends AbstractB
public AbstractB implements C

すべてのサブクラスにインターフェースを実装させ、すべてのサブクラスに実装させるのが理にかなっている場合は、これを使用します。Beagleを拡張すると、AbstractDogはWagを実装します。

public class A extends AbstractB implements C
public class AbstractB implements C

これは冗長ですが、わかりやすくする場合があります。


2番目の段落の「AbstractC」(質問には存在しません)を「AbstractB」に変更する必要があると思います。エディストは少なくとも6文字でなければならないので、編集することはできません。
cellepo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.