秦疆的Java课程笔记:69 面向对象 Super详解

发布时间 2023-12-14 16:48:03作者: Acolyte_9527
  • super调用父类属性
//首先写一个父类
public class Person {  
    protected String name = "1";  
}
//然后写一个子类
public class Student extends Person{  
    private String name = "2";  
    public void test(String name){  
        System.out.println(name);  
        System.out.println(this.name);  
        System.out.println(super.name);  
    }  
}
//最后在Application类中写主程序方法
import OOP.demo.Student;  
public class Application {  
    public static void main(String[] args) {  
        Student student = new Student();  
        student.test("3");  
    }  
}
====运行结果====
3   //这时主程序方法传参给子类的“name”
2   //这是子类中自己的“this.name”
1   //这是子类中调用父类的“super.name”
  • 除了调用属性外,还能调用方法:
//在父类里写一个print方法
public class Person {  
    public void print() {  
        System.out.println("Person");  
    }  
}
//在子类里也写一个print方法,输出不一样。再写一个test方法供Application类调用
public class Student extends Person{  
    public void print() {  
        System.out.println("Student");  
    }  
    public void test(){  
        print();  
        this.print();  
        super.print();  
    }  
}
//在Application类中调用test方法
import OOP.demo2.Student;  
public class Application {  
    public static void main(String[] args) {  
        Student student = new Student();  
        student.test();  
    }  
}
====运行结果====
Student   
Student   //“print()”和“this.print()”都是子类自己的方法,加上this更便于区分
Person   //“super.print()”则是调用的父类方法
  • 当父类中的属性、方法权限为private时,super无法调用。

  • 再从下面的例子看看super的特性

//父类中写一个无参构造
public class Person {  
    public Person() {  
        System.out.println("Person无参执行了");  
    }  
}
//子类中写一个无参构造
public class Student extends Person{  
    public Student() {  
        System.out.println("Student无参执行了");  
    }  
}
//Application类
import OOP.demo3.Student;  
public class Application {  
    public static void main(String[] args) {  
        Student student = new Student();  
    }  
}
====运行结果====
Person无参执行了
Student无参执行了
  • 你会发现new一个子类中的方法时,却先执行了父类的无参构造。这是因为在子类的构造器中有一行隐藏的默认的代码super();,在调用父类的无参构造。
  • 而且,如果你显式定义了super();,然后试图在这行代码之上写子类的方法,会直接报错。也就是说,这行super();必须在子类构造器的第一行。
public class Student extends Person{  
    public Student() {  
        super();   //可以显式地写出来,对运行无影响,别写到构造器外面去了
        System.out.println("Student无参执行了");  
    }  
}
  • 下面的内容秦疆老师讲得很快,且不甚清晰,总之我尽力理清楚。
  • 如果我们在子类中显式定义super();,再加一个有参构造,用this();调用自身的有参构造,父类保持无参:
//父类==============================
public class Person {  
    public Person() {  
    }  
}
//子类==============================
public class Student extends Person{  
    public Student() {  
        super();  
        this("name");   //报错
    }  
    public Student(String name) {   //一个有参构造
    }  
}
  • 这时代码会报错:this();调用必须是构造函数主体中的第一条语句。

  • 如果this();super();调换顺序,则会报错:super();调用必须是构造函数主体中的第一条语句。

  • 如果将父类中的无参构造改为有参构造,子类的无参构造中显式定义super();

//父类==============================
public class Person {  
    public Person(String name) {   //父类改成有参
    }  
}
//子类==============================
public class Student extends Person{  
    public Student() {  
        super();   //报错
    }  
}
  • 按照之前所学,定义了有参构造,那么无参构造要么重新显式定义一个,要么就直接没了。这时,显式调用父类无参构造的super();会报错,因为父类的无参构造已经没有了。
  • 若删除super();语句,子类的无参构造也会报错:父类中没有可用的默认构造参数。(这里的默认构造参数就是无参构造)。
//父类==============================
public class Person {  
    public Person(String name) {
    }  
}
//子类==============================
public class Student extends Person{  
    public Student() {   //报错
    }  
}
  • 若加上显式定义语句super("name")super调用了父类的参数"name",则能正常调用。
//父类==============================
public class Person {  
    public Person(String name) {
    }  
}
//子类==============================
public class Student extends Person{  
    public Student() {  
        super("name");   //不再报错
    }  
}
  • 所以秦疆老师的经验谈:一旦重写了有参构造,先把无参构造加上。

  • 小结:

    • super调用父类的构造方法,必须在子类构造方法的第一行。
    • super只能出现在子类的方法或者构造器中。
    • superthis不能同时调用构造器。
    • super对比this
      • 代表的对象不同:
        • this代表的是本身调用者这个对象。
        • super代表的是父类对象的引用。
      • 使用前提不同;
        • this没有继承也可以使用。
        • super只能在继承条件下使用。
      • 构造方法不同:
        • this();本类的构造。
        • super();父类的构造。