今天,一个学习者想出了一个有趣的查询。我们知道this
关键字用于引用当前对象。但是我无法向他解释this
关键字的行为,如以下代码片段所示。我知道继承是什么:允许访问父类变量和方法。 但是它们是否已复制到子实例的内存区域?,因为我能够使用此关键字访问父类属性。
我能够引用父类变量。我搜索后发现,没有任何内容被虚拟地复制到子类,但是为什么发生以下行为?请说明使用this
的情况。
class Parent {
int a=10;
}
public class Child extends Parent{
void m1(){
System.out.println(a);
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args){
new Child().m1();
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
答案 0 :(得分:1)
实例化一个Child类时,它将包含其自身和Parent的所有成员。但是,“孩子”无法访问“父母”的私人成员:
class Parent {
private int p = 10;
}
public class Child extends Parent{
void m1(){
System.out.println(p); // compilation error
}
}
另一种有趣的情况是,Parent的一个实例尝试访问Parent的另一个实例的私有字段。您认为会发生什么?
public class Parent {
private int p = 11;
public boolean same(Parent other) {
return other.p == p;
}
}
您可能会认为other.p
会导致编译错误,因为p
是私有字段。但是,由于隐私与对象实例无关,而与类有关。因此,Parent中的所有私有字段在所有Parent实例中都是可见的,因此可以正常工作!
答案 1 :(得分:1)
属性a
由Child
继承。因此,您可以在子级中使用this.a
来引用它。
问题应该在哪里?
我搜索后发现,没有任何内容被虚拟复制到子类
您有错误的示例来说明该声明。
(大致)理解的方式是:“在子类中重新声明实例变量时,它们不会被覆盖,因此您不能将实例声明为Parent
,并且期望得到Child.a
该实例是使用new Child()
”创建的。这是有问题的情况的示例:
class Parent {
int a = 10;
}
public class Child extends Parent{
int a = 12; //not overridden
public static void main(String[] args){
Parent child = new Child();
System.out.println(child.a); //This will print 10, not 12
}
}
System.out.println(child.a);
将打印10
,因为变量实例字段不会被覆盖。您可以根据声明的类型(在这种情况下为Parent
)获得值
答案 2 :(得分:0)
请考虑以下代码:
super用于在创建时引用Parent的属性 孩子也一样。
class Product{
String color;
public Product() {
color = "Black";
}
}
class Mobile extends Product{
String color;
Mobile(){
color = "White";
}
void showMobileData(){
System.out.println("this hashCode is "+this.hashCode());
System.out.println("super hashCode is: "+super.hashCode());
System.out.println("color is: "+color);
System.out.println("this.color is: "+this.color);
System.out.println("super.color is: "+super.color);
}
}
public class Test {
public static void main(String[] args) {
//new Mobile().showMobileData();
Mobile mRef = new Mobile();
System.out.println("mRef HashCode: "+mRef.hashCode());
mRef.showMobileData();
}
}