super关键字:
首先回顾一下this关键字,对比学习:
this是一个引用变量,,其中存放了当前对象在堆内存中的地址,代表当前对象。
1.this关键字:
- this关键字能使用在实例方法和构造方法中,不能在静态方法中使用。
- this的语法:this. this()
- this什么时候不能省略?
- this(实参列表)只能出现在构造方法的第一行,表示调用本类的其他构造方法。
2.super关键字:
- super能出现在实例方法和构造方法中,不能在静态方法中使用。
- super的语法是:super. super();
1.关于super();
super()表示在子类的构造方法中调用父类的构造方法!
在具有继承关系的类中,当创建了子类的对象时,没有父类怎么会有子类呢?
所以为了模拟这种思维,子类的构造方法第一行中既没有this()又没有super()的话,会默认有一个super();,表示当前子类的构造方法在执行时先调用了父类的无参构造方法。所以,创建子类对象时,必须保证父类的无参构造方法是存在的!!
可以看出,创建子类对象时,调用了父类的构造方法,实际上Object类是所有类的超类,创建任意一个类的对象最后一定会调用Object类的构造方法!
public class SuperTest01{
public static void main(String[] args){
B b = new B();
}
}
class A{
public A(){
System.out.println("A的无参构造执行了");
}
}
class B extends A{
public B(){
//super();
System.out.println("B的无参构造执行了");
}
}
/*
A的无参构造执行了
B的无参构造执行了
*/
注意:
-
this()和super() 不能共存,它们都是只能出现在构造方法第一行。
-
无论是怎样折腾,父类的构造方法是一定会执行的。(百分百的。)
2.super()内存图分析:
public class SuperTest02{
public static void main(String[] args){
CreditAccount ca1 = new CreditAccount();
System.out.println(ca1.getActNo()+","+ca1.getBalance()+","+ca1.Credit);
//null,0.0,0.0
CreditAccount ca2 = new CreditAccount("111",10000,0.8);
System.out.println(ca2.getActNo()+","+ca2.getBalance()+","+ca2.Credit);
}
}
class Account{//默认继承Object类
private String actNo;
private double balance;
public Account(){
//super();
//this. actNo = null;
//this.balance = 0.0;
}
public Account(String actNo,double balance){
//super();
this.actNo = actNo;
this.balance = balance;
}
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;
}
}
class CreditAccount extends Account{
double Credit;
public CreditAccount(){
//super();
//this.Credit = 0.0;
}
public CreditAccount(String actNo,double balance,double Credit){
//这里想要访问继承的父类型稀有特征不能用this.
super(actNo,balance);
/*
this.setActNo(actNo);
this.setBalance(balance);
*/
this.Credit = Credit;
}
}
总之在构造方法的执行过程中,一连串调用了父类的构造方法,父类又去调用它的父类的构造方法,但实际上整个过程只创建了一个对象。
- super(实际参数列表)的作用是调用父类构造方法来初始化对象内部的父类型特征,因为父类的构造方法是不能继承的。
3.super和this区别:
public class SuperTest03{
public static void main(String[] args){
Vip v = new Vip("张三");
v.shopping();
}
}
class Customer{
String name;
public Customer(){
//super();
}
public Customer(String name){
//super();
this.name = name;
}
}
class Vip extends Customer{
public Vip(){
}
public Vip(String name){
super(name);
}
public void shopping(){
System.out.println(this.name+"shopping!");
System.out.println(super.name+"shopping!");
System.out.println(name+"shopping!");
}
}
/*
张三shopping!
张三shopping!
张三shopping!
*/
注意:
在内存图中分析:
super是this指向的那个对象的一块区域!
4.super.什么时候不能省略?
当对象的父类型特征和本类型属性名相同时,为了区分二者,通过super.表示父类型特征,this.表示本类型特征。
public class SuperTest04{
public static void main(String[] args){
Vip v = new Vip("张三");
v.shopping();
}
}
class Customer{
String name;
public Customer(){
//super();
}
public Customer(String name){
//super();
this.name = name;
}
}
class Vip extends Customer{
String name;//和父类属性同名
public Vip(){
}
public Vip(String name){
super(name);
}
public void shopping(){
System.out.println(this.name+"shopping!");//null
System.out.println(super.name+"shopping!");//张三
System.out.println(name+"shopping!");//null
}
}
5.this是一个引用,存放了当前对象在堆内存中的地址,那super是引用变量吗?
不是。
public class SuperTest05{
/*
输出引用会自动调用Object类的toString()方法;
那super是否也是引用呢?
*/
public static void main(String[] args){
SuperTest05 s = new SuperTest05();
s.doSome();//SuperTest05@15db9742
}
public void doSome(){
System.out.println(this);
//错误: 需要'.'
//System.out.println(super);
}
}
通过这个测试得出的结论:
super 不是引用。super也不保存内存地址,super也不指向任何对象。
super 只是代表当前对象内部的那一块父类型的特征。
super和this都不能使用在静态方法中,包括main方法
6.总结:super的使用方法:
super.属性名:访问父类型的属性;
super.方法名(实参):访问父类中的方法;
super(实参):调用父类的构造方法
public class SuperTest06{
public static void main(String[] args){
Cat c = new Cat();
c.go();
}
}
class Animal{
public Animal(){
}
public void move(){
System.out.println("Animal move!");
}
}
class Cat extends Animal{
public Cat(){
}
public void move(){
System.out.println("Cat move!");
}
//子类的方法
public void go(){
this.move();
super.move();
move();
}
}
/*
Cat move!
Animal move!
Cat move!
*/