目录
- 基本介绍
 
super代表父类的引用,用于访问父类的属性、构造器、方法。
一、基本语法
1.访问父类的属性,但不能访问父类的private属性 super.属性名;
2.访问父类的方法,但不能访问父类的private方法 super.方法名(参数列表);
3.访问父类的构造器 super(参数列表);只能放在构造器的第一句并且只能出现一句
二、super给编程带来的好处/细节
1.调用父类构造器的好处(分工明确,父类属性由父类初始化,子类属性由子类初始化)
2.当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
3.super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。
三、super和this的比较
| 区别点 | this | super | |
|---|---|---|---|
| 访问属性 |   访问本类中的属性,如果本类没有 此属性则从父类中继续查找  | 从父类开始查找属性 | |
| 调用方法 |   访问本类中的方法,如果本类没有 此方法则从父类中继续查找  | 从父类开始查找方法 | |
| 调用构造器 |   调用本类构造器,必须放在构造器的首行  |   调用父类构造器,必须放在 子类构造器的首行  | |
| 特殊 | 表示当前对象 |   子类中访问父类对象 (父类的引用)  | 
super课堂讲解代码
public class super01 {
    public static void main(String[] args) {
        B b = new B();//子类对象
        //b.sum();
        b.Test();
    }
}
public class Base { //父类的父类
    public int n1 = 999;
    public int age = 20;
    public void cal(){
        System.out.println("Base类的cal方法....");
    }
    public void eat(){
        System.out.println("Base类的eat方法....");
    }
}
public class A extends Base{ //父类
    //属性
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;
    //构造器
    public A(){}
    public A(String name){}
    public A(String name, int age){}
    //方法
    public void test100(){}
    protected void test200(){}
    void test300(){}
    private void test400(){}
    //细节补充代码
    public void cal(){
        System.out.println("A类的cal方法....");
    }
}
public class B extends A{ //子类
    //访问父类的属性,但不能访问父类的private属性 super.属性名;
    public void hi(){
        System.out.println(super.n1 + " " + super.n2 + " " + super.n3);
    }
    //访问父类的方法,但不能访问父类的private方法 super.方法名(形参列表);
    public void ok(){
        super.test100();
        super.test200();
        super.test300();
    }
    //访问父类的构造器 super(参数列表); 只能放在构造器第一句,只能出现一句
    public B(){
        //super();
        super("jack",10);
    }
    //细节补充代码
    public int n1 = 888;
    public void cal(){
        System.out.println("B类的cal方法...");
    }
    public void sum(){
        System.out.println("B类的sum方法....");
        //希望调用父类A的cal方法
        //因为子类B没有cal方法,因此可以使用下面三种方式
        //找cal方法时(cal() 和 this.cal()),顺序如下
//         1.先找本类,如果有,则调用
//         2.如果本类没有,则找父类(如果有,并且可以调用,则调用)
//         3.如果父类没有,则继续找父类的父类,直到找到Object类
//         提示:如果查找方法的过程中找到了,但是不能访问,则报错
//              如果查找方法的过程中没有找到,则提示方法不存在
        //cal();
        //this.cal();//等价与 cal();
        //找cal方法(super.cal())的顺序是直接查找父类,其他规则一样
        super.cal();
        //访问属性的规则与找方法的规则一致
        System.out.println(n1);
        System.out.println(this.n1);
        System.out.println(super.n1);
    }
    //编写测试方法Test
    public void Test(){
        //super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,
        //也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,
        // 使用super访问遵循就近原则。A->B->C,当然也要遵守访问权限的相关规则
        System.out.println("super.n1=" + super.n1);
        super.cal();
    }
} 

四、方法重写/覆盖
1.基本介绍
方法重写(覆盖)就是子类有一个方法和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
2.注意事项和使用细节
①子类方法的形参列表,方法名称要和父类的形参列表、方法名称完全一样
②子类方法的返回类型和父类方法的返回类型要一样,或者是父类返回类型的子类。比如:父类返回类型是Object,子类的返回类型是String
③子类方法不能缩小父类方法的访问权限(可以相等或者扩大)
public→protected→默认→private










