从其子 class 的实例访问 super-class 的属性

Accessing the properties of a super-class from an instance of its sub-class

class Person {
    public String name;
    String id;

    public Person() {
        System.out.println("Parent default");
        name = id = "";
    }

    public Person(String name, String id) {
        System.out.println("Parent parameter");
        this.name = name;
        this.id = id;
    }

    void show() {
        System.out.println(this.name + "\n" + this.id);
    }
}

class Student extends Person {

    Student() {}

    Student(String a, String b) {
        super(a, b);
    }
}

class Main {
    public static void main(String args[]) {
        Person p = new Person("A", "AA");
        Student s = new Student("b", "BB");
        s.show();
    }
}

我是java的新手,所以我想了解一些基本的东西,但我失败了。如果我从父 class 继承,这意味着我在子 class 中得到了父 class 的副本,对吗?所以,在这段代码中——如果我引用父 class' show 方法(在 Main class 中),这应该显示父 class' nameid 之前设置的。

但它没有显示——所以我的理解肯定有问题。如何从子 class 访问父 class 的副本?使用子构造函数中的 super 方法?我也想简单了解一下继承的基础知识

您的 child class、'Student' 继承了 parent 的显示方法。

因此,当您创建一个 object 的学生时,带有一些值 b 和 BB,这些值得到显示。

student 的值将通过 student 传递给 parent,因为您调用了 super(a,b) 并将使用从它的 [=23= 获得的 show() 方法显示] class.

希望对您有所帮助。

继承并不像你想象的那样有效,方法和变量被复制,但值不是。

如果你创建一个新的 Person() 并填充它,然后创建一个新的 Student() Person 中的值不会被复制,这是因为值通常基于 class 的实例而不是只是 Classes。有一种方法可以复制它,但通常不会这样做,除非错误地将变量设为静态。

静态变量与 Class 而不是实例关​​联,因此由 Class

的所有实例共享

当您调用 super() 时,您是在使用子项的值调用父项的方法,因此如果您有两个方法,一个重载,一个未重载,那么您可以在需要时调用父项方法,例如,请注意它不会更改之前定义的人 class 只是在 Student

中设置 "parent" name 变量
class Person{
    public Person(String name) {
       this.name = name;
    }
}

class Student extends Person{
    public Student(String name, int grade){
        super(name);
        this.grade = grade;
    }
}

对于静态想法,您可以在所有实例之间共享一个变量。即

class Person{
   static String School = "Wandsworth Primary";
        public Person(String name) {
           this.name = name;
        }
    }

    class Student extends Person{
        public Student(String name, int grade){
            super(name);
            this.grade = grade;
        }

        public show() {
          System.out.println(school);
       }
    }

这与继承无关。你就是不懂classes.

的概念

你创建的ps是完全独立的东西。它们不会相互影响,所以调用 s.show() 永远不会打印 p.

中的值

"But s inherits from p though! So it must have a copy of p!"你争辩了。不,s 没有继承自 p,只有 Student 继承自 Person

并不是 s 复制了 p,而是 Student 复制了 Person

Student中没有show方法,但您仍然可以调用它。为什么?因为Student继承自Person,所以show方法是"copied"到Student.

当你调用 show 时,实际发生的是 Person 中的 show 被调用:

System.out.println(this.name + "\n" + this.id);

如您所见,它会打印调用者(我们知道它是调用者,因为 this 关键字)的名称和 ID。那么这里的来电者是谁? s!这就是它打印学生姓名和 ID 的原因。

如果还不明白,就Student这样想:

class Student {
    public String name;
    String id;

    void show() {
        System.out.println(this.name + "\n" + this.id);
    }    


    Student() {}

    Student(String a, String b) {
        System.out.println("Parent parameter");
        this.name = name;
        this.id = id;
    }
}

看到了吗?我将 Person class 中的所有内容复制到 Student!

考虑以下语句:

Person p = new Person("A", "AA");

这正在创建 Person。它的名称是 "A",它的 ID 是 "AA"

现在考虑这个陈述:

Student s = new Student("b", "BB");

这正在创建一个新的 Student。它还创建了一个 new Person。这怎么可能?那么一个Student就是一个Person。这就是继承的意义。当一种类型扩展另一种类型时,即定义类型之间的 "is a" 关系。

狗扩展了动物,因为狗是动物。 Car 扩展了 Vehicle,因为 Car 是 Vehicle。

因此,当您创建一个新的 Student 时,您正在创建一个 PersonStudent extends Person,所以 StudentPerson。不足为奇,我可能会补充。

super 关键字用于从其子 class 引用父 class 的方法和字段。在你的 Student 构造函数中

Student(String a, String b) {
    super(a, b);
}

您实际上是通过调用 super(a, b) 间接调用 Person 构造函数。因此 new Student("b", "BB") 创建了一个名称 "b" 和 ID "BB"PersonPerson 恰好也是 Student

"a" 和人 "b" 之间没有任何真正的关系(尽管他们可能是远亲)。如果你问 "a" 人她的名字,她会回答 "a"。如果你问 "b" 人的名字,他会回复 "b"。一个人回复另一个人的名字会有点奇怪,所以个人被视为完全不同的人。


另请参阅:Java Inheritance Documentation