Java 继承中的困惑——“继承”的价值;这";在构造函数中打印时

Java 继承中的困惑——“继承”的价值;这";在构造函数中打印时,java,inheritance,Java,Inheritance,我有以下代码 class Test { int i = 0; Test() { System.out.println(this); System.out.println(this.i); } } public class Demo extends Test { int i = 10; Demo() { super(); System.out.println("calling super

我有以下代码

class Test {
    int i = 0;

    Test() {
        System.out.println(this);
        System.out.println(this.i);
    }

}

public class Demo extends Test {
    int i = 10;

    Demo() {
        super();
        System.out.println("calling super");
        System.out.println(this);
        System.out.println(this.i);    
    }

    public static void main(String[] args) throws IOException {    
        Demo d = new Demo();    
    }
}

O/P : Demo@2e6e1408
0
calling super
Demo@2e6e1408
10
当我执行程序并在超级类构造函数和子类构造函数中打印“this”的值时,this(地址位置)的值显示为childClassName@someValue .. 我的问题是,为什么我不能得到测试的值,即,Test@someVal(超级类)当我在超级类中打印“this”的值时。。ASAIK,Super class在内存中也会有一个位置,所以,为什么我不能Test@someValue在第一个SOP中

PS:我知道变量是基于引用类型(LHS)引用的,方法是基于对象类型(RHS)调用的

当我执行程序并在超级类构造函数和子类构造函数中打印“this”的值时,this(地址位置)的值

System.out.println(this)
和默认的
对象#toString
的输出是而不是内存中实例的地址。它只是类的名称和实例的哈希代码,仅此而已。发件人:

class对象的
toString
方法返回一个字符串,该字符串由对象作为实例的类的名称、at符号字符“@”和对象哈希代码的无符号十六进制表示形式组成。换句话说,此方法返回一个等于以下值的字符串:

getClass().getName()+'@'+Integer.toHexString(hashCode())

这是真的

这通常通过将对象的内部地址转换为整数来实现

但它也说

…但是JavaTM编程语言不需要这种实现技术

…当然,JVM可以根据需要在内存中自由移动实例,但不允许更改
hashCode


…为什么我不能得到测试的值,即,Test@someVal(超级类)当我在超级类中打印“this”的值时


有一个实例。该实例是子类的一个实例。当您执行
System.out.println(this)
时,无论您是在基类还是在子类中执行此操作,它仍然是您使用的同一个对象实例。一个对象有它从子类获得的特性,也有它从超类继承的特性,但没有两个单独的实例;有一个实例具有一组组合的功能
super
不是对象引用,尽管它看起来有点像对象引用;这是一种语法机制,专门要求编译器使用实例从超类继承的特性,而不是实例的等效特性(如果它们不同)。

演示由3个类组成:自身、测试和对象。但是Demo的实例是一个对象,在内存中它由它的超类的字段+它自己的字段组成:
Test.i
+
Demo.i
(对象没有字段)。

好的。。。getClass().getName()+'@'+Integer.toHexString(hashCode())。。。这应该引用测试类右侧的当前对象??。。我的意思是,即使在父类中,使用“子对象”作为当前对象是否正确?。父对象将有自己的哈希代码和名称。为什么不使用它呢???@TheLostMind:没有“父对象”。只有一个对象,它具有从子类和超类接收的特性。这是最基本的一点:没有两个独立的对象。有些语言以这种方式进行继承,称为原型继承(例如JavaScript就是其中之一),但Java不是其中之一。Java执行经典继承。那么JVM将如何区分演示类和测试类中的变量“i”。。我在两种情况下都使用了“this”,那么我得到的结果肯定是相同的…@TheLostMind:JVM做簿记来跟踪你所说的
I
。您可以将其视为一个对象有一个名为
Test$i
的私有成员和另一个名为
Demo$i
的私有成员。编译器会根据访问引用时使用的引用类型确定要使用哪些引用。如果引用的类型为
Demo
,则使用
Demo$i
;如果它具有类型
Test
,则使用
Test$i
this
的类型基于编写它的代码(例如
Demo
中的
Demo
Test
中的
Test
),即使
this
的值在这两种情况下是相同的。@TheLostMind:恐怕是错的。:-)字段和方法都是通过引用访问的。我得回去工作了,我建议继续学习教程和阅读相关的内容,你会成功的。但这里的主要收获是:1。有一个对象。2.你对对象的引用类型控制着你能看到什么,以及你看到的东西的哪个版本(
i
成员)。。演示和测试都被合并到内存中的一个对象中?当然,这就是为什么“this”是一样的Demo@2e6e1408这意味着JVM将如何区分演示类和测试类中的变量“i”。。我在两种情况下都使用了“this”,那么我得到的结果肯定是相同的。JVM知道这个.I内部测试是Test.I。如果你想打印Demo.i从测试这样做Demo.this.iThanks:)。。请看我的编辑。。为什么我不能从超类中调用someFunc(),而我可以从子类中调用它??。如果“this”指的是“combinedobject”,那么我应该可以打电话给你,对吧?你最近的编辑似乎在试图把这个问题改成其他问题。简单的答案是类
Test
没有名为
somFunc
的函数,因此它的编译失败<另一方面,code>Demo具有该功能,因此它将编译。这是很基本的