Javaでは、オブジェクト指向プログラミング(OOP)の4つの重要な原則がすべて実装されています:カプセル化、継承、多態性、抽象化。
private、protected、public)とゲッター/セッターを使用してカプセル化を達成します。public class Account { private double balance; public double getBalance() { return balance; } public void deposit(double amount) { this.balance += amount; } }
extendsキーワードを使用して既存のクラスを基に新しいクラスを作成することを可能にします。これにより、コードの再利用が促進されます。public class Animal {} public class Dog extends Animal {}
Animal animal = new Dog(); animal.makeSound(); // Dogの実装が呼び出される
public interface Drawable { void draw(); }
Javaでクラスがインターフェースと抽象クラスの両方を継承し、同じシグネチャのメソッドがある場合はどうなりますか?継承されたクラスはどのような動作を示しますか?
回答: 抽象クラスとインターフェースが同じメソッドシグネチャを定義している場合、派生クラスでそのメソッドを1回実装するだけで済みます。しかし、抽象クラスがそのメソッドを実装している場合、Javaはその実装を使用します。インターフェースのデフォルトメソッドは必要に応じてオーバーライドされます。
interface A { default void foo() { System.out.println("A"); }} abstract class B { void foo() { System.out.println("B"); }} class C extends B implements A {} // new C().foo() は "B" を出力します
物語
銀行のプロジェクトで、開発者はすべてのフィールドを
publicにし、直接アクセスしていました。これにより、オブジェクトの状態が制御不能に変化し、エラーの追跡が困難になりました。その結果、すべてのコードをprivateフィールドとアクセサメソッドを使用するように書き直さなければなりませんでした。
物語
新しい従業員の一人が、基底クラスのprivateメソッドをオーバーライドしようとしましたが、これが多態性を支持するものだと考えていました。しかし、実際には子クラスで新しいメソッドが作成され、基底クラスからの呼び出しは元のバージョンを呼び出し、予期しない動作を引き起こしました。
物語
複数のソースからのデフォルトメソッドを持つインターフェースの使用は、「class X inherits unrelated defaults for Y() from types A and B」というエラーを引き起こしました — 従業員はそのような衝突が子クラスで手動で解決されるべきであることを知らなかったのです。