super

什么是super:
在父和子中有同名的属性,或者说有相同的方法。
如果此时想在子类中访问父中的数据,必须使用“super.”加以区分。
 
1 super是一个关键字,全部小写
    
2 super和this对比着学习
  this:
            this能出现在实例方法中和构造方法中。
            this的语法是:“this.”、“this()”
            this不能使用在静态方法中
            this. 大部分情况下是可以省略的
            this. 什么时候不能省略呢?在区分局部变量和实例变量的时候不能省略
                public void doSome(String a){
                    this.a = a;
                }
            this() 只能出现在构造方法第一行,通过当前的构造方法去调用“本类”中其他的构造方法,目的是:代码复用。
        
        super:
            super能出现在实例方法中和构造方法中。
            super的语法是:“super.”、“super()”
            super不能使用在静态方法中
            super. 大部分情况下是可以省略的
            super. 什么时候不能省略呢?????
            super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中其他的构造方法,
                目的是:创建子类对象的时候,先初始化父类型特征。
                
3 super()
        表示通过子类的构造方法调用父类的构造方法。
        模拟现实世界中的这种场景:要想有儿子,需要先有父亲。
    
4 重要的结论:
        当一个构造方法第一行:
            既没有this()有没有super()的话,默认会有一个super();
            表示通过当前子类的构造方法调用父类无参数构造方法。
            所以必须保证父类无参数构造方式是存在的。
    
5 注意:
        this()和super()不能共存,他们都是只能出现在构造方法第一行。
        
 6 无论是怎样折腾,父类的构造方法一定会执行的。(百分百)
 
super.属性名          【访问父类中的属性】
super.方法名(实参) 【访问父类中的方法】
super(实参)            【访问父类中的构造方法】
 
 
案例1:
/*
    1 super是一个关键字,全部小写
    
    2 super和this对比着学习
        this:
            this能出现在实例方法中和构造方法中。
            this的语法是:“this.”、“this()”
            this不能使用在静态方法中
            this. 大部分情况下是可以省略的
            this. 什么时候不能省略呢?在区分局部变量和实例变量的时候不能省略
                public void doSome(String a){
                    this.a = a;
                }
            this() 只能出现在构造方法第一行,通过当前的构造方法去调用“本类”中其他的构造方法,目的是:代码复用。
        
        super:
            super能出现在实例方法中和构造方法中。
            super的语法是:“super.”、“super()”
            super不能使用在静态方法中
            super. 大部分情况下是可以省略的
            super. 什么时候不能省略呢?????
            super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中其他的构造方法,
                目的是:创建子类对象的时候,先初始化父类型特征。
                
    3 super()
        表示通过子类的构造方法调用父类的构造方法。
        模拟现实世界中的这种场景:要想有儿子,需要先有父亲。
    
    4 重要的结论:
        当一个构造方法第一行:
            既没有this()有没有super()的话,默认会有一个super();
            表示通过当前子类的构造方法调用父类无参数构造方法。
            所以必须保证父类无参数构造方式是存在的。
    
    5 注意:
        this()和super()不能共存,他们都是只能出现在构造方法第一行。
        
    6 无论是怎样折腾,父类的构造方法一定会执行的。(百分百)
*/
public class SuperTest01{
    public static void main(String[] args){
        // 创建子类对象
        /*
            A类的无参构造方法!
            B类的无参数构造方法!
        */
        new B();
    }
}

class A /*extends Object*/{
    // 建议手动的将一个类的无参构造方法写出来。
    public A(){
        super();//调用Object中的无参构造方法
        System.out.println("A类的无参构造方法!");
    }
    
    // 一个类如果没有手动提供任何构造方法,系统会默认提供一个无参数构造方法
    // 一个类如果手动提供了一个构造方法,那么无参数构造系统将不再提供。
    // 错误: 无法将类 A中的构造器 A应用到给定类型
    public A(int a){
        System.out.println("A类的有参数构造方法(int)");
    }
}

class B extends A{
    /*
    public B(){
        //super(100);
        super();
        System.out.println("B类的无参数构造方法!");
    }
    */
    
    public B(){
        // 调用父类中有参数的构造方法
        //this("张三"); //错误: 对super的调用必须是构造器中的第一个语句
        //super(123);//错误: 对this的调用必须是构造器中的第一个语句
        this("zhangsan");
        
        System.out.println("B类的无参数构造方法!");
    }
    
    public B(String name){
        super();// 调用的是父类中的无参构造方法
        System.out.println("B类的有参数构造方法(String)");
    }
}

 

 

 

案例2:

案例2:
public class SuperTest02{
    public static void main(String[] args){
        new C();
        // 先不要看答案哦,要通过自己的努力把答案写出来,那才是真的牛。
        /*
            A的无参数构造方法执行
            B类的有参数构造执行(String)
            C的有参构造方法执行(String,int)
            C的有参构造方法执行(String)
            C的无参数构造方法执行
            
            在java语言中不管是new什么对象,最后老祖宗的Object类的无参构造方法一定会执行。
                (Object类中的无参数构造方法是处于“栈顶部”)
                
            栈顶的特点:
                最后调用,但是最先执行结束。
                后进先出原则。
                
            大家要注意:
                以后写代码的时候,一个类的无参数构造方法还是建议大家手动的写出来。
                如果无参数构造方法丢失的话,可能会影响到“子类对象的构建”。
        */
    }
}

class A{
    public A(){
        System.out.println("A的无参数构造方法执行");
    }
}

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

class C extends B{
    public C(){//这个是最先调用的,但是是最后结束的
        this("zhangsan");
        System.out.println("C的无参数构造方法执行");
    }
    
    public C(String name){
        this(name,20);
        System.out.println("C的有参构造方法执行(String)");
    }
    
    public C(String name,int age){
        super(name);
        System.out.println("C的有参构造方法执行(String,int)");
    }
}

 

 

 

案例3:

/*
    举个例子:在恰当的时间使用:super(实际参数列表);
    注意:在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用他的父类方法,但是实际上对象只创建了一个。
    
    思考:super(实参)到底是干啥的。
        super(实参)的作用是:初始化当前对象的父类特征。
        并不是创建了新的对象,实际上对象只创建了一个。
        
    super关键字代表的是什么?
        super关键字代表的就是“当前对象”那部分父类型特征。
        我继承了我父亲的一部分特征
            例如:“眼睛,皮肤等”
            super代表的就是“眼睛,皮肤等”。
            眼睛,皮肤等 虽然是继承了父亲的,但是这部分是在我身上的。
*/
//测试程序
public class SuperTest03{
    public static void main(String[] args){
        CreditAccount a = new CreditAccount();
        System.out.println("账号:" + a.getActno() + "余额" + a.getBalance() + "信誉度" + a.getCredit());
        CreditAccount b = new CreditAccount("1111",100000,0.99);
        System.out.println("账号:" + b.getActno() + "余额" + b.getBalance() + "信誉度" + b.getCredit());
    }
}

// 银行账户类
// 银行的属性: 账号、余额
class Account{ // 父类
    
    // 属性
    private String actno;
    private double balance;
    
    // 构造方法
    // 无参
    public Account(){
        
    }
    
    // 有参
    public Account(String actno,double balance){
        this.actno = actno;
        this.balance = balance;
    }
    
    // getter and setter 方法  实例方法哦
    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{ // 子类
    
    // 属性:信誉度(诚信值)
    // 子类特有的一个特征,父类没有。
    private double credit;
    
    // 构造方法
    public CreditAccount(){
    
    }
    
    // 构造方法
    // 分析一下程序是否存在编译错误?????
    public CreditAccount(String actno,double balance,double credit){
        // 私有的属性,只能在本类中访问
        /*
        this.actno = actno;
        this.balance = balance;
        */
        // super(); // 默认
        // 以上两行代码在恰当的位置,正好可以使用:super(actno,balance);
        // 通过子类的构造方法调用父类的构造方法。
        super(actno,balance);
        this.credit = credit;
    }
    
    // getter and setter 方法  实例方法哦
    public void setCredit(double credit){
        this.credit = credit;
    }
    
    public double getCredit(){
        return credit;
    }
}

 

案例3内存图:

 

 

 

案例4:

public class SuperTest04{
    public static void main(String[] args){
        Vip v = new Vip("zhangsan");
        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);
    }
    
    // super 和 this都不能出现在静态方法中
    public void shopping(){
        // this表示当前对象
        System.out.println(this.name + "正在购物");
        // super表示的是当前对象的父类特征。(super是this指向的那个对象中的一块空间。)
        System.out.println(super.name + "正在购物");
        // name其实就是this.name
        System.out.println(name + "正在购物");
    }
}

 

 

案例4内存图:

 

 

 

 

案例5:

/*
    this.  和  super. 大部分情况下都是可以省略的。
    
    this. 什么时候不能省略
    public void setName(String name){
        this.name = name;
    }
    
    super.什么时候不能省略
    如果父类和子类有同名属性,当你想访问父类中的那个属性的时候,那么就必须用到super.
*/
public class SuperTest05{
    public static void main(String[] args){
        Vip v = new Vip("zhangsan");
        v.shopping();
    }
}

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

class Vip extends Customer{
    
    // 假设子类也有一个同名属性
    // java中允许在子类中出现和父类一样的同名变量/同名属性。
    String name;
    
    public Vip(){}
    
    public Vip(String name){
        super(name);
        // this name = null;
    }
    
    // super 和 this都不能出现在静态方法中
    public void shopping(){
        // this表示当前对象
        System.out.println(this.name + "正在购物");
        // super表示的是当前对象的父类特征。(super是this指向的那个对象中的一块空间。)
        System.out.println(super.name + "正在购物");
        // name其实就是this.name
        System.out.println(name + "正在购物");
    }
}

 

 

 

案例5内存图:

 

 

 

案例6:

/*
    通过这个测试得出的结论:
        super 不是引用。super也不保存内存地址,super也不指向任何对象。
        super 只是代表当前对象内部的那一块父类型的特征。
*/
public class SuperTest06{
    //实例方法
    public void doSome(){
        // 输出“引用”的时候,会自动调用引用的toString()方法
        // System.out.println(this);
        
        // 错误: 需要'.'
        // System.out.println(super);
    }
    
    // 静态方法
    public static void main(String[] args){
        SuperTest06 s = new SuperTest06();
        // SuperTest06@2ff4acd0
        s.doSome();
        
        // main方法一样的  因为他也是静态的。
        // System.out.println(this);
    }
    
    // 错误: 无法从静态上下文中引用非静态 变量 this
    // 错误: 无法从静态上下文中引用非静态 变量 super
    // 错误: 找不到符号
    /*
    public static void doOther(){
        System.out.println(this);
        System.out.println(super.xxx);
    }
    */
}

 

 

 

案例7:

/*
    在父和子中有同名的属性,或者说有相同的方法。
    如果此时想在子类中访问父中的数据,必须使用“super.”加以区分。
    
    super.属性名          【访问父类中的属性】
    super.方法名(实参)        【访问父类中的方法】
    super(实参)                        【访问父类中的构造方法】
    
    记住一点:私有的只能在本类中访问。
*/
public class SuperTest07{
    public static void main(String[] args){
        Cat c = new Cat();
        /*
            Cat move!
            Cat move!
            Animal move!
        */
        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. 不仅可以访问属性,还可以访问方法。
        super.move();
    }
}
 
posted @ 2020-06-10 01:43  xlwu丶lz  阅读(481)  评论(0编辑  收藏  举报