super关键字

super 和 this对比
使用super 不能 在子类中·访问 父类的private数据。
private类只能在本类当中访问。
super是一个关键字,全部小写。

this:
  this能出现在实例方法 和 构造方法
  this的语法: this.   this()
  this. 大部分可以省略
  this()只能出现在构造方法的第一行,通过当前的构造方法去调用 本类中 的其他构造方法,目的是 代码复用

super:
  super能出现在实例方法 和 构造方法
  super的语法: super.   super()
  super. 大部分不省略
  super()只能出现在构造方法的第一行,通过当前的构造方法去调用 父类中 的构造方法,目的是 创建子类对象的时候,先初始化父类型特征
  super()构造 表示通过子类的构造方法调用
public class Test {
  public static void main(String[] args) {
    new B();
  }
}

class A{
  public A() {
    System.out.println("A类型的无参构造法!");
    //一个类 如果没有手动提供任何构造方法,系统默认提供一个无参数构造方法。
    //一个类 如果手动提供了一个构造方法,那么无参数构造系统将不再提供。
  }
}

class B extends A{
  public B(){
    //这里会默认有个super();
    System.out.println("B类型的无参构造法!");
  }
}

monacoeditor java关键字高亮 java关键字super_父类

super传入参数的例子

//调用父类中有参数的构造方法

monacoeditor java关键字高亮 java关键字super_父类_02


super()有且只能存在一个。

this 和 super都只能出现在 第一行
两者只能存在一个

class B extends A{
  public B(){
    super();
    this("zhangsan"); //error: 对this的调用必须是构造器中的第一个语句

    System.out.println("B类型的无参构造法!");
  }
  public B(String name){
    System.out.println("B类的有参数构造方法(String)");
  }
}

当第一行既没有this() 又没有super(),默认存在super();
this() 和 super() 不能共存,因为其都只能位于 构造函数第一行。
this()通过构造函数 调用当前类 中的 其它构造函数。
super() 通过构造函数 调用父类 中的 其它构造函数。

顺序练习:

package com.bjpowernode.javase.day11;


public class Test {
  public static void main(String[] args) {
    new C();
  }
}

class A{
  public A(){
    System.out.println(" 1 A的无参构造!"); // 1
  }
}

class B extends A{
  public B(){
    System.out.println(" 2 B的无参构造!"); // 2
  }
  public B(String name){
    System.out.println(" 3 B类的有参数构造执行String"); // 3
  }
}

class C extends B{
  public C(){
    this("zhangsan");
    System.out.println(" 4 C的无参构造执行"); // 4
  }
  public C(String name){
    this(name,20);
    System.out.println(" 5 C的有参构造执行String"); // 5
  }
  public C(String name, int age){
    super(name);
    System.out.println(" 6 C的有参数构造执行String and int"); // 6
  }
}
// 输出顺序: 1 3 6 5 4

monacoeditor java关键字高亮 java关键字super_System_03

使用super从而在子类中访问父类的私有属性
例子:

public class Test {
  public static void main(String[] args) {
    CreditAcoount a1 = new CreditAcoount();
    System.out.println(a1.getActno()+","+a1.getBalance() + ","+a1.getCredit());
    CreditAcoount a2 = new CreditAcoount("111",1000,0.99);
    System.out.println(a2.getActno()+","+a2.getBalance() + ","+a2.getCredit());
  }
}

class Account{
  private String actno;
  private double balance;
  
  public Account(){}
  
  public Account(String actno, double balance){
    this.actno = actno;
    this.balance = balance;
  }

  public String getActno() {
    return actno;
  }

  public void setActno(String actno) {
    this.actno = actno;
  }

  public double getBalance() {
    return balance;
  }

  public void setBalance(double balance) {
    this.balance = balance;
  }
}
//信用账户
class CreditAcoount extends Account{
  private double credit; // 诚信值,子类特有特征值
  
  public CreditAcoount(){}
  
  public CreditAcoount(String actno, double balance, double  credit){
//    this.setActno(actno);
//    this.setBalance(balance);
    //在恰当的位置使用 super(actbi,balance);
    super(actno,balance);
    this.credit = credit;
  }
  
  public void doSome(){
    System.out.println(getActno());
  }

  public double getCredit() {
    return credit;
  }

  public void setCredit(double credit) {
    this.credit = credit;
  }
}

monacoeditor java关键字高亮 java关键字super_父类_04


javac 编译

java 运行

super原理

super代表 当前对象的 父类型特征。

monacoeditor java关键字高亮 java关键字super_java_05


但其实整个程序,只在底层创建了一个对象。

只不过,这个对象中的有一部分特征,是从父类中继承过来的。

super(实参) 的作用:初始化 当前对象的父类特征。
并不是创建新对象。实际上对象只创建了 一个。

super关键字代表就是 当前独享 那部分 父类型特征。
我继承了我父亲的一部分特征:
例如:“眼睛,皮肤”
super代表的 就是 眼睛,皮肤。
眼睛,皮肤,虽然是继承自 父亲,但是在我身上长的。

另一个例子 VIP客户案例
public class Test {
  public static void main(String[] args) {
    Vip v = new Vip("张三");
    v.shopping();
  }
}

class Customer{
  String name;

  public Customer(){}

  public Customer(String name){
    this.name = name;
  }
}

class Vip extends Customer{
  public Vip(){}

  public Vip(String name){
    super(name);
  }

  public void shopping(){
    System.out.println(this.name + "正在购物!"); // this表示当前对象
    System.out.println(super.name + "正在购物!"); // 当前对象的父类型特征 super是this指向那个对象中的一块空间。
    System.out.println(name + "正在购物!"); 
  }
}

monacoeditor java关键字高亮 java关键字super_java_06

改进
假设子类中 有 和 父类 同名的属性

public class Test {
  public static void main(String[] args) {
    Vip v = new Vip("张三");
    v.shopping();
  }
}

class Customer{
  String name;

  public Customer(){}

  public Customer(String name){
    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 + "正在购物!"); // this表示当前对象
    System.out.println(super.name + "正在购物!"); // 当前对象的父类型特征 super是this指向那个对象中的一块空间。
    System.out.println(name + "正在购物!");
  }
}

monacoeditor java关键字高亮 java关键字super_构造方法_07

如果子类 和 父类 有 同名属性
想要访问 父类中的 该同名属性 必须在属性名前+super().

this.name 当前对象的name属性
super.name 当前对象的父类型特征中的name属性

super的使用

super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【调用父类的构造方法】

/*
super 不是引用,super也不保存内部地址,super也不指向任何对象。
 */
public class Test {
  // 实例方法
  public void doSome(){
    // 输出 "引用" 的时候,会自动调用引用的toString()方法。
    System.out.println(this); // com.bjpowernode.javase.day11.Test@1d44bcfa 调用的是object的toString方法
//    System.out.println(super.); // 编译error 后面需要加.
  }
  // 静态方法,主方法
  public static void main(String[] args) {
    Test t1 = new Test();
    t1.doSome();
//    System.out.println(this); // error 无法从静态上下文中引用非静态 变量 this
//    System.out.println(super.xxx); // error 无法从静态上下文中引用非静态 变量 super
  }
}
public class Test {
  public static void main(String[] args) {
    Cat c = new Cat();
    c.yiDong();
  }
}

class Animal{
  public void move(){
    System.out.println("Animal move");
  }
}

class Cat extends Animal{
  //对move重写
  public void move(){
    System.out.println("Cat move!");
  }

  public void yiDong(){
    this.move();
    move();
    super.move ();
  }
}

monacoeditor java关键字高亮 java关键字super_System_08

super关键字总结

super 可以出现 在 实例方法 和 构造方法中

super的语法是 super() 和 super.xxx
super不能在静态方法中使用
super.xx 的 super不能在 父类 和 子类 同名的情况下, 想要访问父类中的 该同名的时候 省略 super.

super的使用:
super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【访问父类的构造方法】