开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
super (1)super能出现在实例方法和构造方法中。 (2)super的语法是“super.”和“super()”。 (3) super不能出现在静态方法中。 (4) super大部分情况下是可以省略的。 (5)super.什么时候不能省略呢?
super和this区别是:this可以看做一个引用变量,保存了该对象的地址,是当前对象整体,而super代表的是父类型特征,是子类局部的一些东西,这些继承过来的东西已经在子类里面了,你可以输出整体this,但不能输出父类型特征super。因为super指向的东西不是一个整体,没法打印输出。
System.out.println(this); //输出this.toString()的值 System.out.println(super); //编译报错,需要'.'
当在子类对象中,子类想访问父类的东西,可以使用“super.”的方式访问。例如:方法覆盖后,子类内部虽然重写了父类的方法,但子类也想使用一下父类的被覆盖的方法,此时可以使用“super.”的方式。当子类中出现和父类一样的属性或者方法,此时,你要想去调用父类的那个属性或者方法,此时“super.”不能省略。
this和super都只能在对象内部使用。 this代表当前对象本身,super代表当前对象的父类型特征。
“this.”是一个实例对象内部为了区分实例变量和局部变量。 而“super.”是一个实例对象为了区分是子类的成员还是父类的成员。 父类有,子类也有,子类想访问父类的,“super.”不能省略。
(6)super()只能出现在构造方法的第一行,通过当前的构造方法去调用“父类”中的对应的构造方法,目的是:创建子类对象时,先初始化父类型特征。
用通俗的话来讲,要想有儿子,得先有父亲。
我们来看下面代码: 写两个类,Animal和Cat,Cat继承Animal。
//父类,Animal类 class Animal { //构造函数 public Animal() { System.out.println("Animal类的无参数构造函数执行"); } }
//子类,Cat类 class Cat extends Animal{ //构造函数 public Cat() { System.out.println("Cat类的无参数构造函数执行"); } }
执行下面一行代码:
public static void main(String[] args) { Cat cat = new Cat(); }
运行输出结果为:
Animal类的无参数构造函数执行 Cat类的无参数构造函数执行
我们发现实例化一个子类的对象,也就是调用了子类的构造方法,为什么父类的无参数构造方法也执行了,并在子类构造方法执行之前就已经执行了父类的无参数构造方法,好奇怪。
刚刚在上面的super关键字的使用第6点,我已经说了,super()和this()方法一样,都只能在构造方法的第一行出现。我们猜想,难道子类的构造方法第一行有一个隐形的super()方法?答案是肯定的。
我们把子类的构造方法的第一行给它加上super():
//子类,Cat类 class Cat extends Animal{ //构造函数 public Cat() { super(); System.out.println("Cat类的无参数构造函数执行"); } }
再执行下面代码:
Cat cat = new Cat();
运行输出结果为:
Animal类的无参数构造函数执行 Cat类的无参数构造函数执行
和刚才的子类构造方法没加super()的运行结果是一样的。
所以说当子类的构造方法内第一行没有出现“super()”时,系统会默认给它加上无参数的"super()"方法。
无论你子类构造方法有没有“this()”和“super()”方法,实例化子类对象一定一定会执行对应的父类构造方法,即不管实例化了一个怎样的孩子,它一定会先实例化一个对应的父亲。