134

抽象クラスを使用してインターフェースを実装すると、Java で奇妙なことが起こります。インターフェースのメソッドの一部が完全に欠落している可能性があります (つまり、抽象宣言も実際の実装も存在しない) が、コンパイラは文句を言いません。

たとえば、次のインターフェイスがあるとします。

public interface IAnything {
  void m1();
  void m2();
  void m3();
}

次の抽象クラスは、警告やエラーなしで楽しくコンパイルされます。

public abstract class AbstractThing implements IAnything {
  public void m1() {}
  public void m3() {}
}

理由を説明できますか?

4

7 に答える 7

167

これは、クラスが抽象である場合、定義により、インスタンス化するサブクラスを作成する必要があるためです。サブクラスは、(コンパイラによって) 抽象クラスが省略したインターフェイス メソッドを実装する必要があります。

AbstractThingサンプル コードに従って、メソッドを実装せずに のサブクラスを作成してみてm2、コンパイラが与えるエラーを確認してください。このメソッドを実装する必要があります。

于 2008-10-13T15:04:48.110 に答える
34

まったく問題ありません。
抽象クラスをインスタンス化することはできません..しかし、抽象クラスを使用して、m1() および m3() の共通の実装を格納できます。
したがって m2() の実装は実装ごとに異なりますが、m1 と m3 はそうではありません。異なる m2 実装だけで異なる具体的な IAnything 実装を作成し、DRY 原則を尊重して AbstractThing から派生させることができます。インターフェイスが抽象クラスに対して完全に実装されているかどうかを検証することは無駄です..

更新: 興味深いことに、C# ではこれがコンパイル エラーとして強制されることがわかりました。このシナリオでは、メソッド シグネチャをコピーし、抽象基本クラスで「abstract public」という接頭辞を付ける必要があります.. (毎日新しい何か:)

于 2008-10-13T15:19:19.500 に答える
4

インターフェースとは、メソッドの実装を持たず、宣言だけを行うクラスを意味します。
一方、抽象クラスは、宣言だけで実装なしでいくつかのメソッドとともにいくつかのメソッドの実装を持つことができるクラスです。
抽象クラスへのインターフェースを実装するとき、それは抽象クラスがインターフェースのすべてのメソッドを継承したことを意味します。したがって、すべてのメソッドを抽象クラスに実装することは重要ではありませんが、(継承によっても) 抽象クラスになるため、抽象クラスはここで実装せずにインターフェースにメソッドの一部を残すことができます。ただし、この抽象クラスが具象クラスに継承される場合、実装されていないすべてのメソッドを抽象クラスに実装する必要があります。

于 2013-10-08T01:20:40.583 に答える
3

抽象クラスがインターフェースを実装する場合

インターフェイスのセクションでは、インターフェイスを実装するクラスはインターフェイスのすべてのメソッドを実装する必要があることに注意してください。ただし、クラスが抽象クラスとして宣言されている場合は、インターフェイスのすべてのメソッドを実装していないクラスを定義することができます。例えば、

abstract class X implements Y {   
    // implements all but one method of Y
}

class XX extends X {   
    // implements the remaining method in Y 
} 

この場合、クラス X は Y を完全には実装していないため抽象でなければなりませんが、クラス XX は実際には Y を実装しています。

参照: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

于 2016-10-29T15:43:49.810 に答える
1

メソッドの実装に抽象クラスは必要ありません。したがって、インターフェースを実装していても、インターフェースの抽象メソッドは抽象のままにすることができます。具象クラス (つまり、抽象ではない) にインターフェイスを実装しようとして、抽象メソッドを実装しない場合、コンパイラは次のように通知します。抽象メソッドを実装するか、クラスを抽象として宣言します。

于 2008-10-13T15:21:39.590 に答える