インターフェイスだけでなく抽象クラスも必要ですか?
-
11-07-2019 - |
質問
インターフェイスは100%の抽象クラスなので、効率的なプログラミングのためにインターフェイスを使用できます。抽象クラスがインターフェースよりも優れている状況はありますか?
解決
抽象クラスは、具体的なクラスを作成するときに使用されます。 しかし、すべてのサブクラスにいくつかの共通の状態があることを確認したい または、一部の操作で一般的な実装が考えられます。
インターフェースにはどちらも含めることはできません。
他のヒント
はい、抽象クラスとインターフェースの両方の場所があります。
具体的な例を見てみましょう。抽象 AbstractBankAccount
から CheckingAccount
および SavingsAccount
を作成する方法と、インターフェースを使用して2つのタイプを区別する方法を調べます。アカウント。
最初に、抽象クラス AbstractBankAccount
を示します:
abstract class AbstractBankAccount
{
int balance;
public abstract void deposit(int amount);
public abstract void withdraw(int amount);
}
balance
としての口座残高と、サブクラスによって実装する必要がある2つのメソッド deposit
および withdraw
があります。
ご覧のとおり、抽象クラスは銀行口座の定義方法の構造を宣言します。 @Uriが応答で言及しているように、この抽象クラスには state があり、これは balance
フィールドです。これは、インターフェイスでは不可能です。
今、 AbstractBankAccount
をサブクラス化して、 CheckingAccount
class CheckingAccount extends AbstractBankAccount
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
}
このサブクラス CheckingAccount
では、2つの抽象クラスを実装しました。ここではあまり興味深いことはありません。
今、 SavingsAccount
をどのように実装できますか? CheckingAccount
とは異なり、興味を持ちます。 deposit
メソッドを使用して関心を高めることもできますが、それでも顧客が自分で関心を預けているようにはなりません。したがって、アカウントにお金を追加する別の手段、特に関心のために、たとえば accrueInterest
メソッドがあると、より明確になる可能性があります。
SavingsAccount
にメソッドを直接実装することもできますが、将来関心を引くことができる銀行口座の種類が増える可能性があるため、 InterestBearing
accrueInterest
メソッドを持つインターフェース:
interface InterestBearing
{
public void accrueInterest(int amount);
}
したがって、 InterestBearing
インターフェースを実装することで興味を引くことができる SavingsAccount
クラスを作成できるようになりました。
class SavingsAccount extends AbstractBankAccount implements InterestBearing
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
public void accrueInterest(int amount)
{
balance += amount;
}
}
今、別のタイプのアカウント、たとえば PremiumSavingsAccount
を作成する場合、 AbstractBankAccount
のサブクラスを作成し、 InterestBearing
インターフェースを使用して、別の利付アカウントを作成します。
InterestBearing
インターフェースは、さまざまなクラスに共通機能を追加するように見えます。当座預金口座に関心が生じない場合に、当座預金口座への関心に対処する機能があるとは意味がありません。
そのため、実際には、抽象クラスとインターフェースの両方が共存し、1つの状況で連携する場所があります。
抽象クラスv / sインターフェイスは、Javaに不慣れで、さらに深く掘り下げたい人のために、多くの好奇心/興味/混乱を生み出すトピックの1つです。
この記事はトピックの詳細な説明。
インターフェースよりも実装のない抽象クラスを好む理由がいくつかあります:
- 特定の不可能なキャストとinstanceof操作は、コンパイル時にキャッチできます。
- 後のバージョンで具象メソッドを追加するオプションがあります。
- 以前は、パフォーマンス上の大きなメリットが何年も前にありました。
- 非常に不明瞭なセキュリティの観点から、既存のクラスと抽象クラスのサブクラスを作成して、既存のクラスを取得してメソッドを実装することはできません。
しかし、一方で、インターフェイスのJavaキーワードはソースをよりクリーンにします。
一般的に、インターフェイスはコードが使用するパブリックAPIを記述しますが、抽象基底クラスは実装の詳細として保持し、共通のコードまたは状態を保持して、実装クラスの重複を減らします。
APIでインターフェイスを使用すると、たとえば外部リソースに依存しないテストクラスを使用できるため、(あなたを含む)人々がクラスに対してテストコードを記述しやすくなります。明示的でありながら現実ではシミュレートするのが困難な動作の種類。
したがって、javaはListインターフェースと、実装に必要な労力を最小限に抑えるためのAbstractList抽象基本クラスを提供します。インターフェース...