繁体   English   中英

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

[英]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的新手,所以我想了解一些基本的知识,但是失败了。 如果我从父类继承,则意味着我在子类中获得了父类的副本,对吗? 因此,在这段代码中—如果我引用父类的show方法(在Main类中),则应该显示先前设置的父类的nameid

但是它没有显示出来,因此我确信我有一个问题。 如何从子类访问父类的副本? 使用子构造函数的super方法? 我也想简单地了解继承的基础。

继承与您的想法不太相符,方法和变量被复制,而值未被复制。

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

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

当您调用super()时,您将使用子项的值来调用父级的方法,因此,如果您有两个方法,一个重载而另一个未重载,则可以调用父方法,例如,如果需要,请注意不会更改先前定义的人员类别,只需在“学生”中设置“父母”名称变量

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);
       }
    }

考虑以下语句:

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

这正在创建一个Person 其名称为"A" ,其标识为"AA"

现在考虑以下语句:

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

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

狗扩展了动物,因为狗是动物。 汽车是汽车的扩展,因为汽车是汽车。

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

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

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

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

"a"和人"b"之间没有任何真正的联系(尽管他们可能是远亲)。 如果您问人"a"作为她的名字,她将回答"a" 如果您向人"b"询问名字,他将回答"b" 一个人用别人的名字回答会有点奇怪,所以这些人被视为完全不同的人。


另请参阅: Java继承文档

您的子类“学生”已从父类继承了show方法。

因此,当您创建一个带有b和BB值的学生对象时,就会显示这些值。

自您调用super(a,b)以来,student的值将通过学生传递给父级,并使用从父级类获取的show()方法显示。

希望这对您有所帮助。

这与继承无关。 您只是不了解类的概念。

您创建的ps是完全独立的事物。 它们不会互相影响,因此调用s.show()将永远不会在p显示值。

“但是sp继承的!所以它必须有p的副本!” 你争论了。 不, s不继承自p ,只有Student继承自Person

并非s具有p的副本,而是Student具有Person的副本。

Student ,没有show方法,但是您仍然可以调用它。 为什么? 因为Student继承自Person ,所以show方法被“复制”到Student

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

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

如您所见,它将打印出呼叫者的名字和ID(由于this关键字,我们知道它是呼叫者)。 那么谁是这里的呼叫者? 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM