5参照型変数とインスタンスを別々に考える前回紹介した「アップキャスト」をもう少し深く理解するため、同じクラスを題材に、参照型変数の色々な使用例を見ておきましょう。int型変数のdataフィールドです。フィールドを出力するメソッドです。NormalSuper3クラスから継承した、サブクラス。フィールドとメソッドを追加しています。int型変数のdataSubフィールドです。フィールドを出力するメソッドです。このクラスで追加したフィールドを出力。ついでにスーパークラスのフィールドも出力。このクラスを実行してください。インスタンスを1つ作り数値を入れます。参照をスーパークラスの参照型へとアップキャストします。スーパークラスのフィールドに値を入れて出力します。サブクラスのフィールドに値を入れて出力します。フィールド・メソッドを使うことはできません。シンボルを見つけられません。int型変数のdataフィールドです。フィールドを出力するメソッドです。NormalSuper3クラスから継承した、サブクラス。フィールドとメソッドを追加しています。int型変数のdataSubフィールドです。フィールドを出力するメソッドです。このクラスで追加したフィールドを出力。ついでにスーパークラスのフィールドも出力。このクラスを実行してください。インスタンスを1つ作り数値を入れます。参照をスーパークラスの参照型へとアップキャストします。スーパークラスのフィールドに値を入れて出力します。サブクラスのフィールドに値を入れて出力します。フィールド・メソッドを使うことはできません。シンボルを見つけられません。^}}NormalSuper3クラスとAddedSub3クラスは前ページで紹介したクラスと全く同じで、クラス名が違うだけです。前ページの例との違いは、これらのクラスを使用している箇所(AddedSub3Runnerクラスのmain()メソッド内)です。今回の例では、まずサブクラスの参照型変数に参照を受け取り、それをスーパークラスの参照型変数にアップキャストしている、という点です。インスタンスを1つ作り数値を入れます。参照をスーパークラスの参照型へとアップキャストします。インスタンスを1つ作り数値を入れます。参照をスーパークラスの参照型へとアップキャストします。refSub;まずAddedSub3クラスのインスタンスを作り、その参照をAddedSub3クラスの参照型変数refSubに入れています。これはこれまで紹介してきたものと同じです。次に、refSub変数に入ってる参照を、スーパークラスであるNormalSuper3クラスの参照型変数refSuperに入れています。することで、refSub変数の中の参照がrefSuper変数にコピーされ、その際アップキャストが行われます。アップキャストこの状態では、refSub変数とrefSuper変数の両方からAddedSub3クラスのインスタンスを見ている形になります。この段階で注意して欲しいのは、インスタンスはまったく変化しないという点です。refSuper変数にアップキャストして参照を入れると、refSuper変数がNormalSuper3クラスの参照型変数のため、なんだか「インスタンスまでNormalSuper3クラスになった」と感じるかもしれません。参照をどの参照型変数に入れようと、それによってインスタンスの型が変化することはありません。参照型変数がどう変わろうが、インスタンスには何にも影響がないというわけです。それともうひとつ、参照型変数同士で行う「参照のコピー」でも、アップキャストが行われることを確認してください。前ページでは、インスタンスから返された参照を、直接スーパークラスの参照型変数に入れた時にアップキャストされましたが、今回は参照型変数から参照型変数へのコピーでアップキャストが行われています。このようにアップキャストは「参照を、スーパークラスへの参照型変数に入れる時」に自動的に行われるんだ、ということを憶えておいてください。次に、2つの参照型変数から、スーパークラスのインスタンス内にあるフィールド・メソッドを使ってみましょう。スーパークラスのフィールドに値を入れて出力します。スーパークラスのフィールドに値を入れて出力します。100このように、スーパークラスの参照型変数・サブクラスの参照型変数どちらを通しても同じように使用できます。「refSuper.printData();」の結果から、両方とも同じインスタンスを参照していることも分かると思います。スーパークラスのインスタンスを使う今度はサブクラスのフィールド・メソッドを使ってみましょう。refSub変数、つまりサブクラスの参照型変数から使ってみます。サブクラスのフィールドに値を入れて出力します。サブクラスのフィールドに値を入れて出力します。1サブクラスの参照型変数からは普通に使えます。これはここまで説明してきたものと同じです。refSuper変数、つまりスーパークラスの参照型変数からサブクラスのフィールド・メソッドを使おうとすると、コンパイルエラーになります。フィールド・メソッドを使うことはできません。シンボルを見つけられません。フィールド・メソッドを使うことはできません。シンボルを見つけられません。^つまり、スーパークラスの参照型変数を通してサブクラスのフィールド・メソッドは使えないということです。いうと、「どのクラスのフィールド・メソッドが使えるか」ということは参照型変数の型で決まるからです。参照型変数の型がスーパークラスの場合、スーパークラスのフィールド・メソッドしか使えません。これはインスタンスの型に関係なく、です。参照型変数の型がサブクラスの場合は、スーパークラスのフィールド・メソッドも、サブクラスのフィールド・メソッドも使うことができます。「参照型変数の型」で考えた場合に、その型で使えるフィールド・メソッドが、実際に使うことのできるフィールド・メソッドになるわけです。参照型変数がスーパークラスの場合にはスーパークラスのフィールド・メソッドだけ使えます。参照型変数がサブクラスの場合には、サブクラスのフィールド・メソッドと、スーパークラスのフィールド・メソッドが使えます。このように、使えるフィールド・メソッドは「参照型変数の型」で決まります。インスタンスの型は関係ない、ということです。オブジェクト指向とJavaこのページは、Java言語を用いたオブジェクト指向プログラミングのチュートリアル解説を行う「Javaのオブジェクト指向入門」の一ページです。詳しい説明は「Javaのオブジェクト指向入門」目次をご覧ください。