7JavaがサポートしているOOP(Object-Oriented Programming: オブジェクト指向プログラミング)の4原則とは何ですか。
Javaは、カプセル化、抽象化、継承、ポリモーフィズムの4原則をサポートしています。カプセル化は、公開されたAPIの背後に内部状態を隠蔽します。抽象化は、本質的な振る舞いに着目します。継承は、既存の型に基づいて新しい型を作成します。ポリモーフィズムは、共有された規約を通じてコードが異なる実装を扱えるようにします。実際の開発では、結合度を低く抑えられるため、継承よりもコンポジションが好まれることがよくあります。
interface PaymentService {
void pay(BigDecimal amount);
}
class CardPaymentService implements PaymentService {
@Override
public void pay(BigDecimal amount) {
// payment implementation
}
}
AI コーチを使ってこの質問に答えてみる
8メソッドのオーバーロードとオーバーライドの違いは何ですか?
オーバーロードは、同じ名前でパラメータが異なる複数のメソッドが存在することを意味し、コンパイラが引数の静的な型に基づいて呼び出すメソッドを選択します。オーバーライドは、サブクラスが親クラスのインスタンスメソッドの実装を置き換えることを意味し、実行時ディスパッチによって実際のオブジェクトの型に基づいて呼び出すメソッドが選択されます。なお、staticメソッドはオーバーライドされるのではなく隠蔽(hide)され、privateメソッドはアクセス可能なメンバーとして継承されないためオーバーライドされません。
void send(String message) {}
void send(String message, int priority) {}
class Animal {
void speak() { System.out.println("Animal"); }
}
class Dog extends Animal {
@Override
void speak() { System.out.println("Dog"); }
}
AI コーチを使ってこの質問に答えてみる
9インターフェイスと抽象クラスの違いは何ですか?
インターフェイスは規約(コントラクト)を定義するものであり、抽象メソッド、デフォルトメソッド、静的メソッド、定数、およびプライベートヘルパーメソッドを含めることができます。一方、抽象クラスはこれらに加えて、インスタンスの状態、コンストラクタ、protectedフィールド、共通の実装、および抽象メソッドや具象メソッドを持つことができます。クラスが継承(extend)できるクラスは1つのみですが、インターフェイスは複数実装(implement)できます。独立した規約を定義する場合はインターフェイスを使用し、実装や状態を共有する密接に関連した型を定義する場合は抽象クラスを使用します。
interface Repository<T> {
Optional<T> findById(long id);
}
AI コーチを使ってこの質問に答えてみる
10final キーワードにはどのような意味がありますか?
final 変数は一度しか代入できませんが、final な参照であっても参照先のオブジェクト自体が不変(イミュータブル)になるわけではありません。final メソッドはオーバーライドできず、final クラスは継承(拡張)できません。final は設計の意図を明確にし、参照の再代入や継承を制限しますが、それ単体で完全なイミュータブルモデルやスレッドセーフ性を提供するものではありません。
final int maxAttempts = 3;
final List<String> names = new ArrayList<>();
names.add("Alice"); // allowed
public final void validate() {}
public final class Token {}
AI コーチを使ってこの質問に答えてみる
11Javaにおけるレコード(record)とは何ですか?
レコード(record)は、イミュータブル(不変)なデータキャリアを定義するための簡潔な構文です。コンパイラによって、privateかつfinalなフィールド、コンストラクタ、アクセサ、equals、hashCode、toStringが自動生成されます。レコードはDTO(Data Transfer Object)や値オブジェクト、メソッドの返却値に適しています。ただし、すべてのドメインエンティティを代替できるわけではありません。コンパクトコンストラクタでバリデーションを追加することは可能ですが、複雑な状態変更を伴う振る舞いや遅延ロード、継承を前提としたデータモデルにはレコードはあまり適していません。
public record User(long id, String name) {}
public record Order(List<String> items) {
public Order {
items = List.copyOf(items);
}
}
AI コーチを使ってこの質問に答えてみる
12Javaで不変(イミュータブル)オブジェクトを作成するにはどうすればよいですか?
クラスを `final` にするか継承を厳密に制限し、フィールドを `private final` に設定した上で、セッターメソッドを設けずコンストラクタで入力値のバリデーションを行います。可変な入力オブジェクトに対しては防御的コピーを作成し、取得時にはコピーまたは変更不能なビューを返します。完全な不変性(ディープイミュータビリティ)を実現するには、すべてのネストされた内部状態も不変である必要があります。`final` フィールドは安全な公開(safe publication)を支援しますが、可変なコレクションや可変なネストオブジェクトをそのまま公開してしまうと、論理的に可変なオブジェクトになってしまいます。
public final class User {
private final String name;
private final List<String> roles;
public User(String name, List<String> roles) {
this.name = name;
this.roles = List.copyOf(roles);
}
public List<String> getRoles() {
return roles;
}
}
AI コーチを使ってこの質問に答えてみる