1. 文法レベルの違い
抽象クラスはメンバー メソッドの実装の詳細を提供できますが、インターフェイスにはパブリック抽象メソッドのみが存在できます (もちろん、デフォルトのインスタンス メソッド、静的メソッドなどがあります)。
抽象クラスのメンバー変数はさまざまな型にすることができますが、インターフェイスのメンバー変数は public static Final 型のみにすることができます。
クラスは 1 つの抽象クラスからのみ継承できますが、クラスは複数のインターフェイスを実装できます。
2つ目はデザインレベルの違い
1) 抽象クラスは物の抽象化、つまりクラスの抽象化ですが、インターフェイスは動作の抽象化です。
抽象クラスは属性や動作を含むクラス全体を抽象化しますが、インターフェイスはクラスの部分 (動作) を抽象化します。
簡単な例を挙げると、飛行機と鳥は別のものですが、共通点は「空を飛べる」ということです。次に、設計するときに、飛行機を飛行機のようなものとして、鳥を鳥のようなものとして設計することはできますが、飛行の機能をクラスとして設計することはできないため、それは単なる動作の機能であり、飛行の抽象的な説明ではありません。物事のクラス。このとき、フライトはメソッド fly() を含む Fly インターフェイスとして設計でき、Airplane と Bird はそれぞれのニーズに応じて Fly インターフェイスを実装します。戦闘機や民間航空機などのさまざまな種類の航空機については、Airplane を直接継承すれば十分ですが、鳥についても同様で、さまざまな種類の鳥は Bird クラスから直接継承できます。ここから、継承は「かどうか」の関係であるのに対し、インターフェイスの実装は「存在するかどうか」の関係であることがわかります。クラスが特定の抽象クラスを継承する場合、サブクラスはその抽象クラスの型でなければならず、インターフェイスの実装は、鳥が飛べるかどうか(または飛ぶ特性を持っているかどうかなど)に関係します。 、飛行できる場合は、このインターフェイスを実装できます。飛行できない場合は、このインターフェイスを実装しないでください。
2) 設計レベルが異なり、抽象クラスは多くのサブクラスの親クラスとしてテンプレート設計となります。インターフェイスは動作仕様であり、放射状の設計です。テンプレートデザインとは何ですか?最も単純な例として、誰もが ppt でテンプレートを使用したことがあります。テンプレート A を使用して ppt B と ppt C をデザインする場合、ppt B と ppt C の共通部分はテンプレート A です。共通部分を変更する必要がある場合は、変更するだけで済みます。これを変更するには、テンプレート A で問題ありません。ppt B と ppt C を再度変更する必要はありません。また、放射状の設計では、たとえば、あるエレベーターに何らかのアラームが装備されている場合、アラームを更新すると、すべてのアラームを更新する必要があります。つまり、抽象クラスの場合、新しいメソッドを追加する必要がある場合は、抽象クラスに特定の実装を直接追加でき、サブクラスを変更する必要はありませんが、インターフェイスの場合は、インターフェイスが変更された場合は、インターフェイス クラスのすべての実装をそれに応じて変更する必要があります。
ドアとアラームの例を分析してみましょう。ドアには open( ) と close( ) という 2 つのアクションがあります。現時点では、抽象クラスとインターフェイスを通じてこの抽象概念を定義できます。
-
抽象 クラス ドア {
-
パブリック 抽象 void open();
-
パブリック 抽象 void close();
-
}
または:
-
インターフェース ドア {
-
パブリック 抽象 void open();
-
パブリック 抽象 void close();
-
}
しかし、ドアにアラーム( ) の機能を持たせる必要がある場合、それを実現するにはどうすればよいでしょうか? ここに 2 つのアイデアがあります。
1) これら 3 つの関数をすべて抽象クラスに配置します。この方法では、この抽象クラスから継承されたすべてのサブクラスが警報機能を持ちます。ただし、一部のドアは必ずしも警報機能を持っているわけではありません。
2) これら 3 つの関数をすべてインターフェースに配置します。アラーム関数を使用する必要があるクラスは、このインターフェースに open( ) と close( ) を実装する必要があります。おそらく、このクラスには open( ) と close( ) がまったくありません。 . 火災警報器のような2つの機能。
ここから、ドアの open()、close()、alarm() が 2 つの異なる動作カテゴリに属していることがわかります。open() と close() はドア自体の固有の動作特性に属し、alarm() は、追加動作を拡張しました。したがって、最善の解決策は、alarm() の動作を含むアラームをインターフェイスとして個別に設計し、ドアを開くと閉じる 2 つの動作を含む個別の抽象クラスとして設計することです。次に、Door クラスを継承し、Alarm インターフェイスを実装するように警報ドアを設計します。
-
インターフェースアラーム{
-
ボイド アラーム();
-
}
6. 抽象 クラス Door {
-
ボイド オープン();
-
void close();
-
}
-
class AlarmDoor extends Door 実装アラーム {
-
void oepn() {
-
//....
-
}
-
void close() {
-
//....
-
}
-
void アラーム() {
-
//....
-
}
-
}