zoukankan      html  css  js  c++  java
  • 指向父类的引用——super

    参考:

    https://blog.csdn.net/yongbutingxide/article/details/82669054#1.super()%E7%9A%84%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B%20%E4%B8%80%E4%B8%80%E4%B8%80%E5%AD%90%E7%B1%BB%E9%87%8D%E5%86%99%E7%88%B6%E7%B1%BB%E7%9A%84%E6%96%B9%E6%B3%95

    https://www.cnblogs.com/yyy6/p/8976584.html

    一、用法

            super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用。如果父类由没有默认的无参构造方法,编译器就会报错,super()语句必须是构造方法的第一个子句。

      定义子类的一个对象时,会先调用子类的构造函数,然后在调用父类的构造函数,如果父类函数足够多的话,会一直调用到最终的父类构造函数,函数调用时会使用栈空间,所以按照入栈的顺序,最先进入的是子类的构造函数,然后才是邻近的父类构造函数,最后再栈顶的是最终的父类构造函数,构造函数执行是则按照从栈顶到栈底的顺序依次执行.

      现在以Bird--> Animal --> Object 为线举例说明

     1 public class Animal {
     2     int eye = 2;
     3     public Animal(){
     4         super();
     5         System.out.println("动物");
     6     }
     7     
     8     public void run(){
     9         System.out.println("动物有不同走路方式");
    10     }
    11     
    12     public static void main(String[] args) {
    13         Bird b = new Bird();
    14         b.run();
    15     }
    16 }
    17 
    18 class Bird extends Animal{
    19     public Bird(){
    20         super();
    21         System.out.println("鸟类");
    22     }
    23 
    24     @Override
    25     public void run() {
    26         // TODO Auto-generated method stub
    27         super.run(); // 通过super可以用父类方法和属性
    28         System.out.println("鸟是飞飞飞飞飞飞");
    29         System.out.println("鸟类有"+super.eye+"只眼睛");
    30     }
    31     
    32 }

    结果:

    动物
    鸟类
    动物有不同走路方式
    鸟是飞飞飞飞飞飞
    鸟类有2只眼睛

    Bird--> Animal --> Object 图形分析如下:

     更加详细的例子在下面:

    1.super()的使用实例 一一一子类重写父类的方法

     1 public class A {
     2     
     3     private String nameA="A";
     4     
     5     public void getName() {
     6         System.out.println("父类"+nameA);
     7     }
     8     public static void main(String[] args) {
     9     }
    10     
    11 }
    12 
    13 
    14 public class B extends A{
    15     private String nameB="B";
    16     
    17     @Override
    18     public void getName() {
    19         System.out.println("子类"+nameB);
    20         super.getName();
    21     }
    22     
    23     public static void main(String[] args) {
    24         B b=new B();
    25         b.getName();
    26     
    27     }
    28 }

    结果:

    2.super()的使用实例 一一一子类重写父类的变量

     1 public class A {
     2     
     3      String nameA="A";
     4 
     5 }
     6 
     7 public class B extends A{
     8      String nameA="B";
     9     
    10     
    11     public void getName() {
    12         System.out.println("子类"+nameA);
    13         System.out.println("父类"+super.nameA);
    14     }
    15     
    16     public static void main(String[] args) {
    17         B b=new B();
    18         b.getName();
    19     
    20     }
    21 }

    结果:

    3.super()的使用实例 一一一在子类的构造方法中

    编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器;此时可以省略不写。如果想写上的话必须在子类构造函数的第一句,可以通过super来调用父类其他重载的构造方法,只要相应的把参数传过去就好。

    因此,super的作用主要在下面三种情况下:

    1、调用父类被子类重写的方法;

    2、调用父类被子类重定义的字段(被隐藏的成员变量);

    3、调用父类的构造方法;

    其他情况,由于子类自动继承了父类相应属性方法,关键字super可以不显示写出来。

     4.关于构造方法中super()

    第一种情况:编译不通过

     

    分析:

    如果一个类中没有写任何的构造方法,JVM会生成一个默认的无参构造方法。在继承关系中,由于在子类的构造方法中,第一条语句默认为调用父类的无参构造方法(即默认为super(),一般这句话省略了)。所以当在父类中定义了有参构造函数,都是没有定义无参构造函数时,IDE会强制要求我们定义一个相同参数类型的构造器。

    在本例中JVM默认给B加了一个无参构造方法,而在这个方法中默认调用了super(),但是父类中并不存在该构造方法

    第二种情况:编译不通过

    同样编译错误,相同的道理,虽然我们在子类中自己定义了一个构造方法,但是在这个构造方法中还是默认调用了super(),但是父类中并不存在该构造方法

    第三种情况:成功编译通过

     1 public class A {
     2     public A(String s) {
     3         
     4     }
     5 
     6 }
     7 
     8 public class B extends A{
     9     public B(String s) {
    10         super(s);
    11     }
    12 }

    分析:

    所以,只要记住,在子类的构造方法中,只要里面没有显示的通过super去调用父类相应的构造方法,默认都是调用super(),即无参构造方法,因此要确保父类有相应的构造方法。

    我们通过super是不能访问父类private修饰的变量和方法的,因为这个只属于父类的内部成员,一个对象是不能访问它的private成员的。

  • 相关阅读:
    数据更新
    MVC学习笔记
    const关键字同static readonly 的区别
    RSS
    C语言中取地址跟C++中的引用是一个意思吗?
    生产者消费者模式
    使用foreach的时候,不能对List进修改,怎么办?
    SQL查询
    Windows下的Java访问USB设备解决之道(翻译Java libusb / libusbwin32 wrapper)
    Java SE 6d新特性: 编译器 API
  • 原文地址:https://www.cnblogs.com/qiaoxin11/p/12543715.html
Copyright © 2011-2022 走看看