Java
1class Main {
2 public static void main(String[] args) {
3 String str = new String("sss");
4 Object obj = new String("ooo");
5 CharSequence cs = new String("ccc");
6 System.out.println("str = " + str);
7 System.out.println("obj = " + obj);
8 System.out.println("cs = " + cs);
9 obj = str;
10 System.out.println("obj = " + obj);
11 str = (String)cs;
12 System.out.println("str = " + str);
13 }
14}
new String("sss") でインスタンス化した String オブジェクトで、
String型の変数 str を初期化するのは分かるが、
new String("ooo") でインスタンス化した String オブジェクトで、
Object型の変数 obj を初期化できるのはなぜか、
という質問でしょうか?
それは、Stringクラスが Objectクラスを継承しているからです。
また、Stringクラスは CharSequenceインターフェイスを実装しているから、
CharSequence cs = new String("ccc"); も同様にできるのです。
obj = str; で Object型の変数 obj に String型の変数 str をなぜ代入できるのか?
という質問でしょうか?
実は obj も str も参照型といって、
その変数自身にオブジェクトを持っているのではありません。
オブジェクトを参照しているだけです。
代入前は、obj は "ooo" を値に持つ Stringオブジェクトを参照していましたが、
代入後は、obj は "sss" を値に持つ Stringオブジェクトを参照するようになります。
"ooo" を値に持つ Stringオブジェクトは誰も参照しなくなるので破棄されます。
"sss" を値に持つ Stringオブジェクトは 2つの変数 obj と str の両方から
参照されます。
"sss" を値に持つ Stringオブジェクト自身は 1つのままです。
オブジェクトがコピーされて 2つのオブジェクトになったわけではありません。
あるクラスをインスタンス化したオブジェクトは、その継承元の変数や
実装しているインターフェースの変数でも参照できます。
ただ、継承元の変数を継承先の変数に代入する場合はキャストが必要になります。
それが、str = (String)cs; です。
以上、理解できたかどうかコメントをお願いします。