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`this`在继承情况下实际指的是什么?_Java_Oop_Inheritance_Constructor_This - Fatal编程技术网

Java`this`在继承情况下实际指的是什么?

Java`this`在继承情况下实际指的是什么?,java,oop,inheritance,constructor,this,Java,Oop,Inheritance,Constructor,This,为什么以下Java代码会产生: 10 superclass 有关守则是: class SuperClass { int a; public SuperClass() { this.a = 10; } private void another_print() { System.out.println("superclass"); } public void print() { System.ou

为什么以下Java代码会产生:

10
superclass
有关守则是:

class SuperClass {
    int a;

    public SuperClass() {
        this.a = 10;
    }

    private void another_print() {
        System.out.println("superclass");
    }

    public void print() {
        System.out.println(this.a);
        this.another_print();
    }
}

class SubClass extends SuperClass {
    int a;

    public SubClass() {
        this.a = 20;
    }

    private void another_print() {
        System.out.println("subclass");
    }

    public void print() {
        super.print();
    }
}

public class Main {
    public static void main (String[] args) {
        SubClass c = new SubClass();
        c.print();
    }
}
从来没有创建过
超类的实例,不是吗?
Java不仅开始寻找从
超类调用的方法,它甚至不知何故知道
a=10

让我们考虑类似的Python代码:

class SuperClass:
    def __init__(self):
        self.a = 10

    def another_prn(self):
        print('superclass')

    def prn(self):
        print(self.a)
        self.another_prn()

class SubClass(SuperClass):
    def __init__(self):
        self.a = 20

    def another_prn(self):
        print('subclass')

    def prn(self):
        super().prn()

c = SubClass()
c.prn()
正如我所料:

20
subclass
我的同事(Python不喜欢Java的人)给出的唯一解释是:“Python不是真正的OOP语言”。一点也不令人信服


更新:
private void another_print()
是我的错误,我应该在子类的print中使用
protected

您只需调用super类的print方法。 当然,它会打印超级类中的a

这里有两个独立的a字段。字段不受重写的约束,只有方法被重写。超级类有一个a字段,您在子类中有另一个a字段


如果另一种语言产生了另一种结果,这并不奇怪。另外,我不确定您的Python代码在逻辑上是否与Java代码等效/类似

这是Java中构造函数调用的顺序。
子类
中,当实例化
c
时,构造函数隐式调用
超类
公共超类()
)的默认构造函数(它必须这样做)。然后
a
超类中被设置为10

现在我们已经完成了
超类
构造函数,我们回到
子类
的构造函数,它分配
a=20
。但是字段在java中不受重写的约束,因此
超类中的
a
仍然是10

很明显,我们调用
c.print()
,它调用
子类的
print
,它调用
超类的
print
(by
super.print()
),它打印
a
,就像你记得的那样。然后
另一个\u print
(由于它是
private
,所以不会被覆盖)只打印
超类
,我们就完成了。

My解释了代码可能无法按预期工作的原因。 下面是您最可能期望它如何工作的代码。注意代码中的注释

static class SuperClass {
    int a; // only declare field in superclass to avoid hiding

    public SuperClass() {
        this.a = 10;
    }

    // make method protected, public, or package private to allow children to override it
    protected void another_print() {
        System.out.println("superclass");
    }

    public void print() {
        System.out.println(this.a);
        this.another_print();
    }
}

static class SubClass extends SuperClass {
    public SubClass() {
        this.a = 20;
    }

    @Override
    protected void another_print() {
        System.out.println("subclass");
    }

    public void print() {
        super.print();
    }
}


public static void main (String[] args) {
    SubClass c = new SubClass();
    c.print();
}
这会打印出来

20
subclass

我调试了稍加修改的代码,发现:

  • 子类
  • 与Python不同,Java可以使用多个相同名称的变量(正如peter.petrov在他的文章中提到的,但我没有马上得到它)
  • 其中一个
    a
    s来自
    子类,第二个来自
    超类(作为隐式超类构造函数调用,同样与Python不同)
  • this.a
    test\u super()
    test\u sub()
    中有一个不同的值,考虑到
    this
    是一个
    子类,Java文档如下所示:
  • 是对当前对象的引用,即调用其方法或构造函数的对象


    我想我可以接受这样一个事实,
    这个
    将包含整个依赖关系树中的所有变量,Java将根据上下文选择要使用的变量。

    不一样。python没有私有方法。您不能重写超类方法,因为它是私有的。变量a也被隐藏,因为这两个类都声明了它。您可以自由地告诉您的同事Java也不是纯OOP语言(Python可能是,尽管其他人可能知道得更好)。这与
    所指的内容无关,而是编译器如何解析方法调用和字段名。我习惯于在Java中包含
    @Override
    注释,即使它不是必需的。当某些内容没有被正确覆盖时,编译器会抱怨