一、基础知识
1、super不是引用类型,super中存储的不是内存地址,super指向的不是父类对象
2、super指代的是当前子类对象的父类特征 (如图)
3、什么时候使用super
子类和父类中都有某个数据,例如:子类父类都有name的属性
如果要在子类中访问父类中的name属性,需要用super.name
4、super可以用在什么地方?
第一:super可以用在成员方法中,不能用在静态方法中
第二:super可以用在构造方法中
举个栗子
测试类Test
public class Test{
public static void main(String[] args) {
Manager m = new Manager();
m.m1();
}
}
子类Manager
public class Manager extends Employee{
String name = "hl";
// 子类将父类中的work方法重写
public void work() {
System.out.println("mavager is working");
}
public void m1() {
// this.work();
work();
super.work();
System.out.println(this.name);
System.out.println(super.name);
}
// this和super相同,都不能用在静态上下文中
// public static void m1() {
// System.out.println(super.name);
// }
}
父类Employee
public class Employee {
String name = "yx";
public void work() {
System.out.print("employee is working");
}
}
输出
输出:
mavager is working
employee is workinghl
hl
yx
二、super关键字用在构造方法中
语法:super(实参);
作用:通过子类的构造方法去调用父类的构造方法
语法规则:一个构造方法第一行如果没有this(...)也没有显示的去调用super(...),系统会默认调用super();
注意:
1、super(...);的调用只能放在构造方法的第一行
2、super(...)和this(...)不能共存
3、super(...);调用父类构造方法,但是不会构造父类对象。(即:构造方法执行,不一定创建对象。)
4、在java语言中,只要是创建java对象,那么object中的无参数构造方法一定会执行
5、父类的构造方法并不会被子类继承,而是被子类调用
6、单例模式的缺点:单例模式的类型无法被继承
举一个 super关键字用在构造方法中 的栗子
测试类Test:
public class Test{
public static void main(String[] args) {
DebitAccount da = new DebitAccount("007",0.1, 100); // 输出:Account的无参数构造方法执行!
System.out.println(da.getActno() + " " + da.getBalance() + " " + da.getDebitAccount());
}
}
父类Account
public class Account {
//账号
private String actno;
//余额
private double balance;
public Account() {
// super(); 隐藏的哦!
System.out.println("Account的无参数构造方法执行!");
}
// 创建对象
public Account(String actno,double balance) {
this.actno = actno;
this.balance = balance;
// System.out.println(this.actno,this.balance);
}
// setter and getter
// 重新对成员变量赋值
public void setActno(String actno) {
this.actno = actno;
}
public String getActno() {
return actno;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
}
子类DebitAccount:
public class DebitAccount extends Account{
// 独特属性
// 信誉度
private double debit;
// Constructor
public DebitAccount() {
// super(); 隐藏的哦! Account的无参数构造方法执行!
}
public DebitAccount(String acton,double balance,double debit) {
// 通过子类的构造方法去调用父类的构造方法,作用是:给当前子类对象中的父类型特征赋值。
super(acton, balance);
this.debit = debit;
}
// setter and getter
public void setDebitAccount(double debit) {
this.debit = debit;
}
public double getDebitAccount() {
return debit;
}
}
提问:为什么要通过子类的构造函数调用父类的构造函数,再赋值哪,而不用setter方法妮?
答:通过子类的构造方法去调用父类的构造方法,作用是:给当前子类对象中的父类型特征赋值。(可以认为是初始化,而setter方法可以理解为是数据更新)。