// クラスAの定義
class A {
String val = "A"; // Aに属するインスタンス変数valを"A"に初期化
void print() {
// printメソッドはvalの値をコンソールに出力する
System.out.println(val);
}
}
// クラスBはクラスAを継承する
class B extends A {
String val = "B"; // クラスBのインスタンス変数valを"B"に初期化。これはクラスAのvalを隠蔽する
}
// メインクラス
public class Main {
public static void main(String[] args) {
A a = new A(); // Aのインスタンスを生成
B b = new B(); // Bのインスタンスを生成
// A型の変数aを通じてvalを出力する。これは"A"を出力する
System.out.println(a.val);
// B型の変数bを通じてvalを出力する。静的な型(宣言された型)がAであるため、これは"A"を出力する
// Javaでは、フィールドのアクセスは静的な型に基づくため、実行時の型Bのvalではなく、宣言された型Aのvalが使用される
System.out.println(b.val);
// Aのインスタンスでprintメソッドを実行する。これは"A"を出力する
a.print();
// Bのインスタンスでprintメソッドを実行する。Bはprintメソッドをオーバーライドしていないため、
// 継承されたAのprintメソッドが実行され、これも"A"を出力する
b.print();
}
}
このコードを実行すると、以下のような出力が得られます。
A
A
A
A
フィールドへのアクセスは宣言された型に基づいて行われるため、b.valの参照は、インスタンスがBであっても、宣言された型がAであるためAのvalを指します。これによりAの値が出力されます。また、print()メソッドはどちらのクラスにもオーバーライドされていないため、どちらのインスタンスから呼び出されてもAのprint()メソッドが実行されます。
Top comments (0)