Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:What';当使用super调用时,隐藏超类字段的值是多少?_Java_Oop_Inheritance_Overriding - Fatal编程技术网

Java:What';当使用super调用时,隐藏超类字段的值是多少?

Java:What';当使用super调用时,隐藏超类字段的值是多少?,java,oop,inheritance,overriding,Java,Oop,Inheritance,Overriding,考虑以下示例: public class Main { public static void main(String[] args) { System.out.println(new Maruti().howManyTires()); new Maruti().getColor(); } } 输出为: 1 Magenta 我的问题是,当通过super调用超类'howmanyires函数时,这个引用显然是子类的引用(通过调用getColor方法显

考虑以下示例:

public class Main
{
    public static void main(String[] args) {
        System.out.println(new Maruti().howManyTires());
        new Maruti().getColor();
    }
}
输出为:

1
Magenta
我的问题是,当通过
super
调用超类'
howmanyires
函数时,
这个
引用显然是子类的引用(通过调用
getColor
方法显示)。但是,它返回超类“
tires
字段

我知道字段只是隐藏的,不会被覆盖,但除非这些字段绑定到类(像类变量),否则调用超类“
howManyTires
方法应该返回由
this
引用(属于子类)绑定的
tires

我知道字段只是隐藏的而不是覆盖的

没错。在由
new Maruti
创建的对象中有两个
tires
字段,
Car
tires
字段和
Maruti
tires
字段。访问哪一个取决于用于访问对象的引用的类型。
this
的类型由方法所在的类决定:
this
Maruti
方法中具有类型
Maruti
方法在
Car
中的类型为
Car
。这就是为什么
Maruti
howManyTires
访问
Maruti
轮胎
,以及
Car
howManyTires
访问
汽车
轮胎
的原因,即使在这两种情况下
所指的对象都是
Maruti
对象

对于公共字段和更明显的类型,这可能更容易看到:

class Base {
    public int a = 1;
}

class Sub extends Base {
    public int a = 2;
}

public class Main {
    public static void main(String[] args) {        
        Sub s = new Sub();
        Base b = s;
        System.out.println(s.a); // 2
        System.out.println(b.a); // 1
    }
}
s
类型为
Sub
b
类型为
Base
。它们都引用相同的对象,但请注意用于访问字段的引用类型如何影响访问哪个字段

这适用于字段,而不适用于方法:

class Base {
    public int a = 1;
    public int method() {
        return 1;
    }
}

class Sub extends Base {
    public int a = 2;
    public int method() {
        return 2;
    }
}

public class Main {
    public static void main(String[] args) {        
        Sub s = new Sub();
        Base b = s;
        System.out.println(s.a);        // 2
        System.out.println(b.a);        // 1
        System.out.println(s.method()); // 2
        System.out.println(b.method()); // 2
    }
}

始终是对当前类的引用。毫无例外。(
从不引用超类)我知道字段仅隐藏而不被覆盖:显然,否。如果它返回10,则意味着Maruti中的字段轮胎覆盖Car中的字段轮胎。字段在编译时静态解析。编译Car类时,编译器会为howManyTires生成字节码,该字节码读取并返回Car.tires字段的值。字段值在运行时不会以多态方式解析。@jbnize关于这应该是谁的副本的问题,讨论了字段不被重写而只被复制的简单情况。这个问题问为什么当超类的
This
引用指向子类时,超类“
howManyTires
返回(编辑:超类“
轮胎
字段。它不返回。它返回1。1是超类
轮胎
字段的值。字段未被重写的简单情况是唯一存在的情况。字段不会被覆盖。方法可以是。不是田地。编译方法Car.howmanyires()时,this
的编译时类型为Car。返回Car.tires字段的值。这就是我的意思,但键入了错误的单词。如果
this
引用子类,那么为什么
this.tires
返回超类“
tires
?显然,答案是字段取决于
this
的编译时类型,而方法取决于其运行时类型。但是,仅仅说字段不被重写,而方法被重写,这一点并不明显。如果波顿的人没有给出他的答案(以及随后的编辑),我就不会理解这一点。这就是为什么这个问题不应该在这里被标记为“魔鬼代言人”:Car.howManyTires()方法使用
this
,但它可以访问汽车的轮胎。@jbnitet-True。但是
Car中的
这个
的类型。howManyTires()
Car
,对吗?即使对象是
Maruti
,引用的类型也是
Car
,这解释了为什么会得到
Car
轮胎。或者这个解释有点不恰当?这确实是你答案中缺少的重要部分。我甚至会说:Car.howManyTires()是Car中声明的编译时类型
this
。@JBNizet-重写,我明白你的意思了。我想写“再次感谢!”但是,嗯,我似乎没有在上面说“谢谢”无论如何:谢谢!总是很荣幸:-)
class Base {
    public int a = 1;
}

class Sub extends Base {
    public int a = 2;
}

public class Main {
    public static void main(String[] args) {        
        Sub s = new Sub();
        Base b = s;
        System.out.println(s.a); // 2
        System.out.println(b.a); // 1
    }
}
class Base {
    public int a = 1;
    public int method() {
        return 1;
    }
}

class Sub extends Base {
    public int a = 2;
    public int method() {
        return 2;
    }
}

public class Main {
    public static void main(String[] args) {        
        Sub s = new Sub();
        Base b = s;
        System.out.println(s.a);        // 2
        System.out.println(b.a);        // 1
        System.out.println(s.method()); // 2
        System.out.println(b.method()); // 2
    }
}