インスタンスの代入について

ちょっと友人からJavaのここが分からないと聞かれたんですが、

public class Person {
    Person() {
        //...
    }
    void method() {
        System.out.println("This is Person.");
    }
}

public class Student extends Person {
    Student() {
        //...
    }
    void method() {
        System.out.println("This is Student.");
    }
}

public class Test {
    public static void main(String[] args){
        Student s = new Student();
        Person p = s;
        s.method();
        p.method();
    }
}


実行すると、

This is Student.
This is Student.

になります。


ここで友人が頭をかかえてました。

「なんで別の型に代入できるの。意味が分からん
 しかもpはPerson型なのにStudentのメソッド呼ばれてるし」

そこで前回の、JavaC#では、インスタンスはポインタだと考えるということを思い出すと、参照だけを渡していると考えられないでしょうか。


StudentクラスはPersonクラスのサブクラスなので、暗黙にアップキャストが行われ、型チェックが問題なく通って、アドレスの代入が行われる、と。


つまり、今 s が指しているアドレスが p に代入されるというわけです。


C言語で表現すると、

#include <stdio.h>

int main(){
    int p;
    int* q;
    
    p = 10;
    q = &p;
    
    printf("p: %x, q: %x\n", &p, q);
    
}
p: bffffa08, q: bffffa08

こんな感じでしょうか。ちょっと正確じゃないかもですが。


そういうわけで型チェックは問題なく、参照だけが渡されるので、

This is Student.
This is Student.

という結果になるんじゃないかな、と。


間違っていたりしたら指摘お願いしますです。