1. タイプキャスト
参照型(クラス)を格納する変数も別の型に変換できます。ただし、これは単一の型階層内でのみ機能します。簡単な例を見てみましょう。次のクラス階層があり、下のクラスが上のクラスを継承しているとします。
参照型およびプリミティブ型の型キャストも、拡張と縮小のいずれかに分類されます。
Cat クラスが Pet クラスを継承し、さらに Pet クラスが Animal クラスを継承していることがわかります。
次のようなコードを書くと:
Animal kitten = new Cat();
これは拡張型変換です。暗黙的キャストとも呼ばれます。catオブジェクトを参照するようにcat参照を拡張しました。このような型変換を行うと、子猫参照を使用して、 Catクラスには存在するがAnimalクラスには存在しないメソッドを呼び出すことができなくなります。
縮小変換 (または明示的なキャスト) は逆方向に発生します。
Cat cat = (Cat) kitten;
kitten変数 (型はAnimal )に格納されている参照をCat型にキャストすることを明示的に示しました。
2. オブジェクトの種類を確認する
しかし、ここでは非常に注意する必要があります。これを行う場合:
Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;
コンパイラはこのコードを許可しますが、プログラムを実行するとエラーが発生します。JVM は例外をスローします。
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf
Catオブジェクトへの参照は、型が Cat クラスの祖先である Pet、Animal、または Object である変数にのみ保存できます。
何故ですか?
ここで重要なのは、オブジェクト参照がそのオブジェクトのメソッドと変数を参照するために使用されるということです。そして、Animal 変数を使用して Cat オブジェクトへの参照を保存する場合、何の問題もありません。Cat型には常に Animal 型の変数とメソッドがあり、それらは継承されています。
しかし、JVM で Cat オブジェクトへの参照を Wolf 変数に格納できる場合は、 grayWolf変数を使用して、その変数に格納されている Cat オブジェクトに存在しないメソッドを呼び出そうとする状況が発生する可能性があります。。だからこそ、この取り決めは許されません。
instanceof
Java には、オブジェクトが特定の型であるかどうか、したがって特定の型の変数に格納できるかどうかを確認できる特別な演算子があります。とてもシンプルに見えます:
variable instanceof Type
例:
Animal beast = new Cat();
if (beast instanceof Wolf)
{
Wolf grayWolf = (Wolf) beast;
}
このコードは実行時であってもエラーを引き起こしません。
状況を説明する例をさらにいくつか示します。
拡張型変換 | 説明 |
---|---|
|
これは古典的な拡張変換であり、型変換演算子は必要ありません。これで、クラス内で定義されたメソッドのみがオブジェクト
|
ナローイング型変換 | |
|
従来の絞り込み変換:型チェックとキャスト演算子を追加する必要があります。 変数にはオブジェクト Cow cow への参照が格納されますWhale 。 これが当てはまることを確認し、(絞り込み) 型変換を実行します。または、次のようにも呼ばれます。
型キャスト
。
|
|
オブジェクトの型を確認せずに参照型を絞り込むことができます。 変数が ではないオブジェクトを参照している 場合、 が生成されます。 cow Whale InvalidClassCastException |
3. 元のメソッドの呼び出し:super
キーワード
親クラスのメソッドをオーバーライドするとき、独自のメソッドに置き換えるのではなく、わずかに補足するだけでよい場合があります。
私たちのメソッド内で親クラスのメソッドを使用して、独自のコードの一部を実行できれば素晴らしいでしょう。あるいは、最初に独自のコードを実行してから、親クラスのメソッドを呼び出すこともできます。
Java ではまさにそれが可能です。親クラスのメソッドを呼び出すには、次のようにします。
super.method(arguments);
例:
class PeaceTime
{
public double getPi()
{
return 3.14;
}
}
class WarTime extends PeaceTime
{
public double getPi()
{
return super.getPi()*2; // 3.14*2
}
}
戦時には、 の値がPi
6 より大きくなる可能性があります。もちろん冗談ですが、この例はこれがどのように機能するかを示しています。
もう少しわかりやすくするために、さらにいくつかの例を示します。
コード | 説明 |
---|---|
|
Cow そしてWhale クラス |
|
画面出力は次のようになります。
|
これは大変なことです。正直に言うと、これはOOPで最も難しいことの 1 つです。そうは言っても、それを知り、理解する必要があります。
GO TO FULL VERSION