Super
1、super是一个关键字,全部小写。
2、super和this对比着学习。
this:
this能出现在实例方法和构造方法中。
this的语法是:“this.”、“this()”
this不能使用在静态方法中。
this. 大部分情况下是可以省略的。
this.什么时候不能省略呢? 在区分局部变量和实例变量的时候不能省略。
public void setName(String name){
this.name = name;
}
this() 只能出现在构造方法第一行,通过当前的构造方法去调用“本类”中其它的构造方法,目的是:代码复用。
super:
super能出现在实例方法和构造方法中。
super的语法是:“super.”、“super()”
super不能使用在静态方法中。
super. 大部分情况下是可以省略的。
super.什么时候不能省略呢?父类和子类中有同名属性,或者说有同样的方法,想在子类中访问父类的,super. 不能省略。
super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
super的使用:
super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【调用父类的构造方法】
上面就是关于super的用法总结,下面结合实际的代码来看super的作用。
首先定义A,B两个类,构成继承关系
class A{
public A(){
System.out.println("A类的无参数构造方法!");
}
}
class B extends A{
public B(){
System.out.println("B类的无参数构造方法!");
}
}
此时可以看到,我们给A和B两个类提供了2个无参构造方法,在调用时会输出一段话。然后在下面的函数中去创建B对象,会输出什么呢?
public class SuperTest01{
public static void main(String[] args){
new B();
}
}
令我们惊讶的是,我们得到了如下的输出结果:
A类的无参数构造方法!
B类的无参数构造方法!
我们只是新建了对象B,但是却也输出了A的语句,可以证明,在创建对象B时,也调用了A的构造方法!(值得注意的是,其实我们仍然只是创建了一个对象,并不是创建了2个!)
那么也就意味着,在B的调用方法中,有一句隐藏的语句调用了A的构造方法。
当一个构造方法第一行既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。
所以必须保证父类的无参数构造方法是存在的。
public B(){
surper();//这里如果不写别的的话,那么他是默认有一句surper()的
System.out.println("B类的无参数构造方法!");
}
}
注意:this()和super() 不能共存,它们都是只能出现在构造方法第一行。
也就是说,无论如何,当你去创建子类对象时,父类的构造方法是一定会执行的。(其道理就跟有儿子的前提一定是有爸爸一样)
所以,如果在父类A中有一个有参数的构造方法,
同理我们也可以在子类中通过surper(参数列表)去调用
从而起到初始化父类中特征的目的。
Surper何时不能省略
当父中有,子中又有,如果想在子中访问“父的特征”,super. 不能省略。
例如以下代码
class A{
int id;
}
class B extends A{
int id;
public void test{
System.out.println(id);
System.out.println(this.id);
System.out.println(super.id);
}
}
上面test方法中的三句输出是不一样的,前两句是一样的,这两个id都是指的子类B中的id
最后一句使用了super.去访问,所以这个id是父类A中的id
Super是引用吗?
首先回顾this,我们前面提到,如果在创建了一个对象后,直接输出他的this
具体见前面的博客
System.out.println(this);
我们会得到一串东西,类似于
类名@2f92e0f4
具体含义见前面博客
那是因为当你直接输出this时,其实会去调用Object类中的toString方法(见前)
我们如果直接输出super呢?
System.out.println(super);
我们会得到编译错误!
编译错误: 需要'.'
可以证明,super起码不是引用。
其实,super也不保存内存地址,super也不指向任何对象。super 只是代表当前对象内部的那一块父类型的特征。