抽象クラスと抽象インターフェイスは、すべてのオブジェクト指向プログラミング言語で非常に人気があります。そして、ほとんどすべての Java インタビューで、このトピックに関する少なくとも 1 つの質問に遭遇します。インターフェイスはソフトウェア設計者の間で人気があるため頻繁に言及されますが、抽象クラスに関する質問も時々出てきます。後者は、たとえば Java 開発経験が 2 年以内のジュニア開発者のポジションへの応募者によく聞かれるのに対し、インターフェースに関する質問は、経験がすでに 4 年を超えている人の面接で最もよく聞かれます。これらは通常、Decorator パターンや Factory パターンなどの Java デザイン パターンに関する他の質問と併せて尋ねられます。
この記事では、Java のさまざまなレベルの面接で尋ねられた、抽象クラスとインターフェイスに関する一般的な質問を取り上げます。それらのほとんどは、初心者の Java プログラマーにとっても難しくありません。これらはほとんどが純粋な知識に関する質問ですが、
Java の抽象クラスとインターフェイスの違いや、インターフェイスではなく抽象クラスをいつ選択するかなど、一部の質問は非常に難しい場合があります。このトピックに関する 12 の興味深い質問を提供します。
インタビューで質問されたことがある、または抽象クラスとインターフェイスに関する価値のある質問をしなければならなかったが、それがこのリストに載っていない場合は、コメントで共有してください。 |
1. Java では抽象クラスにコンストラクターを含めることはできますか?
はい、Java の抽象クラスでは、コンストラクターを宣言および定義できます。抽象クラスのインスタンスを作成することは不可能であるため、このようなコンストラクターは、コンストラクターのチェーンを形成する場合、つまり特定の実装クラスのインスタンスを作成する場合にのみ呼び出すことができます。しかし、その後面接官が「抽象クラスのインスタンスを作成できない場合、コンストラクターには何の意味があるのでしょうか?」と質問したと想像してください。重要なのは、抽象クラスで宣言され、さまざまな実装で使用される共通変数の初期値を設定するために引き続き使用できるということです。コンストラクターを宣言しない場合でも、コンパイラーはデフォルトの引数なしのコンストラクターを抽象クラスに追加します。これがないと、コンストラクターの最初のステートメントが
super()
Java のデフォルトのスーパークラス コンストラクターへの暗黙的な呼び出しになるため、サブクラスはコンパイルされません。
2. Java の抽象クラスはインターフェイスを実装できますか? すべてのメソッドを実装する必要があるのでしょうか?
はい、抽象クラスは を使用してインターフェイスを実装できます
implements
。これらは抽象的なため、すべてのメソッドを実装する必要はありません。型を宣言するための抽象基本クラスとインターフェイスを用意することをお勧めします。例としては、インターフェイス
java.util.List
と対応する抽象クラスがあります
java.util.AbstractList
。
AbstractList
すべての共通メソッドを実装するため、特定の実装 ( や
LinkedList
など
ArrayList
) は、インターフェイスを直接実装する場合のように、すべてのメソッドを実装する必要はありません
List
。このソリューションは、インターフェイスを使用して型を宣言する利点と、すべての共通動作を 1 か所で実装する抽象クラスの柔軟性を組み合わせたものです。ジョシュア・ブロックの著書
『Java. 『Effective Programming』には、Java でのインターフェイスと抽象クラスの使用に関する優れた章があり、より深く理解するには、この章を勉強するのが理にかなっています。
3. 抽象クラスはfinalにできますか?
いや、彼には無理だ。このキーワードは、
final
クラスが階層の最上位にあり、子孫を持つことができないことを意味します。そして、継承者のない抽象クラスは、インスタンスを作成することが不可能であるため、真空中の球状の馬と同じです
abstract class
。したがって、クラスが と
abstract
の両方である場合
final
、そのクラスには子孫がなく、インスタンス化できません。
abstract
クラスと を作成すると、Java コンパイラはエラーをスローします
final
。
4. Java の抽象クラスは静的メソッドを持つことができますか?
はい、抽象クラスは静的メソッドを宣言および定義できます。Java で静的メソッドを作成する一般原則に従う必要があるのは、Java で静的メソッドをオーバーライドすることができないため、静的メソッドはオブジェクト指向設計では望ましくないからです。抽象クラスに静的メソッドが使用されることは非常にまれですが、正当な理由がある場合は、静的メソッドの使用を妨げるものはありません。
5. 抽象クラスをインスタンス化することは可能ですか?
いいえ、それはできません。抽象クラスの本質は、それが完全ではないということであり、その子孫クラスで完成する必要があります。つまり、このクラスは使用する準備ができていません。たとえば、一部のメソッドが実装されていない場合があります。クラスは使用する準備ができていないため、そのオブジェクトを作成できません。ただし、抽象クラスの継承者のインスタンスを作成することはできます。プログラムが抽象クラスをインスタンス化しようとすると、Java コンパイラはエラーをスローします。
6. 抽象クラスには抽象メソッドが必要ですか?
いいえ、抽象クラスには抽象メソッドを含めることはできません。
abstract
Java では、宣言にキーワードを使用するだけでクラスを抽象化できます。コンパイラは、このクラスのインスタンスの作成を許可しないなど、構造上の制限を強制します。ところで、抽象クラスまたは抽象インターフェイスに抽象メソッドが存在すべきかどうかについては議論の余地があります。プログラマが抽象クラスを見たときに最初に考えるのは抽象クラスであるため、抽象クラスには抽象メソッドが必要であると私には思われます。これは、驚きを最小限に抑えるという原則によく適合します。
7. Java の抽象クラスとインターフェイスの違いは何ですか?
これは最も重要であり、最も古典的な Java 面接の質問の 1 つです。あらゆるレベルの Java 面接でこの質問を何度見たか数え切れません。この質問が興味深いのは、特に申請者が例を提示する機会があることです。抽象化、カプセル化、ポリモーフィズム、継承など、オブジェクト指向プログラミングの基本に関する質問に答えるのは簡単ですが、そのような微妙なニュアンスになると、求職者は混乱し、最初に思いついたことを言ってしまうことがよくあります。
この質問に対する答えは別の記事に値します (特に Java 8 での変更後) が、簡単に言うと次のようになります。
- インターフェイスはオブジェクトの動作 (メソッド) のみを記述しますが、状態 (フィールド) を持ちません ( を除く
public static final
)。一方、抽象クラスは状態 (フィールド) を持つことができます。
- 抽象クラスを継承(拡張)し、インターフェースを実装(実装)します。継承できるクラスは 1 つだけですが、インターフェイスは必要なだけ実装できます。インターフェイスは、別のインターフェイスを拡張(拡張)できます。
- 抽象クラスは、「is-a」関係がある場合に使用されます。つまり、サブクラスが基本抽象クラスを拡張し、相互にまったく関連していない異なるクラスによってインターフェイスを実装できます。
8. インターフェイスよりも抽象クラスを優先したり、その逆を選択したりするのはどのような場合ですか?
これは、抽象クラスとインターフェイスに関する以前の質問の続きです。構文上の違いが何であるかを知っていれば、決定を下す際の決定要因となるため、この質問に答えることで問題が生じることはありません。公開されたインターフェイスに新しいメソッドを追加することはほとんど不可能であるため、さらなる開発が必要になる可能性がある場合には、抽象クラスを使用することをお勧めします。Java での抽象クラスの開発は、インターフェイスの開発よりも簡単です。同様に、インターフェイスにメソッドが多すぎて、それらをすべて実装するのが本当に面倒な場合は、デフォルトの実装用に抽象クラスを作成することをお勧めします。このパターンは Java コレクション パッケージでも踏襲されており、抽象クラスは
AbstractList
のデフォルト実装を提供します
List
。
次の場合は抽象クラスを使用します。
- 密接に関連する複数のクラス間でコードを共有したいと考えています。
- 抽象クラスを拡張するクラスには、多くの共通のメソッドやフィールドがあること、または
public
(たとえば、protected
やprivate
) 以外のアクセス修飾子が必要であることが期待されます。
- 非静的または
не-final
フィールドを宣言したいと考えています。これにより、メソッドが属するオブジェクトにアクセスしてその状態を変更できるメソッドを定義できます。
次の場合にインターフェイスを使用します。
- 無関係なクラスがインターフェイスを実装することが期待されます。たとえば、インターフェイス
Comparable
とインターフェイスCloneable
は、多くの無関係なクラスによって実装されます。
- 特定のデータ型の動作を定義したいと考えていますが、それを誰が実装するかは気にしません。
- 複数の型の継承を使用したい。
9. Java の抽象メソッドとは何ですか?
抽象メソッドは本体のないメソッドです。メソッドを定義せずに、
abstract
メソッド宣言内のキーワードを使用して宣言するだけです。Java 言語のインターフェース内で宣言されたすべてのメソッドは、デフォルトでは抽象です。Java の抽象メソッドの例を次に示します。
public void abstract printVersion();
このメソッドを実装するには、抽象クラスを拡張し、このメソッドをオーバーライドする必要があります。
10. Java の抽象クラスにメソッドを含めることはできますかmain
?
はい、Java の抽象クラスにはメソッドを含めることができます
main
。これは単なる別の静的メソッドであるためです。抽象クラスは、
main
インスタンス化しない限り、メソッドを使用して実行できます。私が言いたかったのはそれだけです。また、抽象クラスとインターフェイスは、オブジェクト指向の分析および設計プロセスにおける重要な設計上の決定事項であり、柔軟なシステムを作成したい場合は、当然ながら十分な注意を払って使用する必要があることを覚えておいてください。
GO TO FULL VERSION