ある面接で、インターフェースと抽象クラスの違いを説明するように求められました。
私の返答は次のとおりです。
Java インターフェースのメソッドは暗黙的に抽象的であり、実装を持つことはできません。Java 抽象クラスには、デフォルトの動作を実装するインスタンス メソッドを含めることができます。
Java インターフェースで宣言された変数は、デフォルトでは final です。抽象クラスには、非 final 変数が含まれる場合があります。
Java インターフェースのメンバーは、デフォルトで public です。Java 抽象クラスには、private、protected などの通常のクラス メンバーの種類を設定できます。
Java インターフェースはキーワード「implements」を使用して実装する必要があります。Java 抽象クラスはキーワード「extends」を使用して拡張する必要があります。
インターフェースは別の Java インターフェースのみを拡張できますが、抽象クラスは別の Java クラスを拡張して複数の Java インターフェースを実装できます。
Java クラスは複数のインターフェースを実装できますが、拡張できるのは 1 つの抽象クラスだけです。
しかし、面接官は納得せず、この説明は「書物的な知識」を表しているだけだと言いました。
彼は私にもっと実践的な回答を求め、実際の例を使って、インターフェースよりも抽象クラスを選択する必要があるのはどのような場合かを説明しました。
どこで私は間違えましたか?
ベストアンサー1
まず例を挙げます。
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
アプリケーションに 3 つのデータベースがあるとします。その場合、各データベースの実装ごとに、上記の 2 つのメソッドを定義する必要があります。
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
しかし、encryptPassword()
データベースに依存せず、各クラスで同じである場合はどうなるでしょうか? その場合、上記は適切なアプローチではありません。
代わりに、次のアプローチを検討してください。
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
これで、各子クラスで、データベースに依存するメソッドを 1 つだけ実装する必要があります。