从其子类的实例访问超类的属性

时间:2016-10-22 08:02:20

标签: java inheritance super

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很新,所以我想了解一些基本的东西,但我失败了。如果我从父类继承,这意味着我得到了子类中父类的副本,对吧?所以,在这段代码中 - 如果我引用父类' show方法(在Main类中),这应该显示父类'先前设置的nameid

但它没有显示 - 所以我的理解肯定存在问题。如何访问父类'从儿童班复制?使用来自child的构造函数的super方法?我也想知道继承的基本原理。

4 个答案:

答案 0 :(得分:3)

请考虑以下声明:

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

这是创建Person。其名称为"A",其ID为"AA"

现在考虑这个陈述:

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

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

狗延伸动物,因为狗是动物。汽车延伸车辆,因为汽车是一种车辆。

因此,当您创建新的Student时,您正在创建PersonStudent extends PersonStudentPerson。不出所料,我可以补充一下。

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

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

您实际上是通过调用Person间接调用super(a, b)构造函数。因此,new Student("b", "BB")会创建名为Person且标识为"b"的{​​{1}}。 "BB"恰好也是Person

Student和人"a"之间没有任何真正的关系(尽管他们可能是远房堂兄弟)。如果您向"b"人询问姓名,她将回复"a"。如果您要求"a"人提供姓名,他将回复"b"。让一个人回复别人的名字会有点奇怪,所以这些人被视为完全不同的人。

另请参阅:Java Inheritance Documentation

答案 1 :(得分:2)

您的孩子课程,'学生'从父母那里继承了show方法。

因此,当您创建一个学生对象时,会显示某些值b和BB,这些值会显示出来。

学生的值将通过学生传递给父母,因为你打电话给super(a,b),并且将使用从它的父类获得的show()方法显示。

希望这会对你有所帮助。

答案 2 :(得分:2)

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

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

静态变量与Class相关联,而不是与实例相关联,因此该类的所有实例共享

当你调用super()时,你用父子的值调用父方法,所以如果你有两个方法,一个重载而一个不重,那么你可以调用父方法,如果你需要,例如,注意它没有改变先前定义的人类只是设置"父母"学生中的名字变量

TypeScript

对于静态构思,您可以跨所有实例共享变量。即

class Person{
    public Person(String name) {
       this.name = name;
    }
}

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

答案 3 :(得分:1)

这与继承无关。你只是不了解课程的概念。

您创建的ps是完全独立的事情。他们不会相互影响,因此调用s.show()将永远不会打印p中的值。

"但s继承自p!所以它必须有p的副本!"你争辩说。不,s不会从p继承,只有Student继承自Person

s不是p的副本,而是Student的副本Person

Student中,没有show方法,但您仍然可以调用它。为什么?由于Student继承自Person,因此show方法已被"复制"到Student

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

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

正如您所看到的,它打印了来电者(我们知道它的来电者,因为this关键字)名称和ID。那么这位来电者是谁? s!这就是它打印学生姓名和身份的原因。

如果你仍然不明白,只要想到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类复制到Student