写点什么

JAVA 面向对象 (十二)-- 关键字 super

用户头像
加百利
关注
发布于: 3 小时前

super:

1.定义:

在 JAVA 类中使用 super 来引用父类的成分,用 this 来引用当前对象,如果一个类从另外一个类继承,我们 new 这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用 super 来引用,this 指的是当前对象的引用,super 是当前对象里面的父对象的引用。

2.使用:

super 关键字同 this 相似,调用时同样有三种应用:


  • 调用父类可调用属性

  • 调用父类可调用方法

  • 调用父类对应构造方法


应用一:调用父类属性:


super 关键字一般用于含有继承关系,我们还是用例子演示具体调用方式,如现在有一父类 Person,该类含有属性(id,name,sex),还有一子类 Student,该类继承 Person 类,并含有自己特有的属性分数(StudentScore),那么 我们如何在子类中调用父类定义的共同属性呢?代码如下:


父类:


package cn.hz;
/** * @author hz * @version 1.0 * 父类 */public class Person { public Integer id; //属性:学生编号 public String name; //属性:学生姓名 public String sex; //属性:学生性别}
复制代码


子类:


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public void show(){ System.out.println("学生信息如下:姓名:"+super.name+",性别:"+ super.sex+"编号:"+super.id+",分数:"+this.studentScore); }}
复制代码


在子类中调用父类定义属性,语法如下:


super.属性
复制代码


特别注意,子类在调用父类属性时,一定注意属性权限修饰符(具体使用见见前面章节继承中权限修饰符表),并不是父类的所有属性子类都能通过 super 调用,如对父类进行封装,属性使用 private 完成封装,在这种场合我们就无法直接调用父类属性,如何操作呢?需要调用父类的方法进行操作。


应用二:调用父类方法:


子类继承父类,则可以使用父类的属性和方法,前面我们看了子类如何调用父类的属性,接着我们来看看子类如何调用父类的方法:


父类:


package cn.hz;
/** * @author hz * @version 1.0 * 父类: 封装 */public class Person { private Integer id; //属性:学生编号 private String name; //属性:学生姓名 private String sex; //属性:学生性别
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public void test(){ System.out.println("父类方法"); }}
复制代码


子类:


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public void show(){ System.out.println("学生信息如下:姓名:"+super.getName()+",性别:"+ super.getSex()+"编号:"+super.getId()+",分数:"+this.studentScore); }
public void test2(){ System.out.println("调用父类方法"); super.test(); }}
复制代码


上述代码父类 Person 完成了封装,子类无法调用父类属性,但是子类可以通过调用父类中对属性提供的公共方法 set 方法从而获取父类的值,在父类中还定义了一个普通方法,子类同样可以通过关键字 super 进行调用。


注意: 在该处因为子类已经将父类的属性和方法继承了,所以在调用父类的方法时 super 省略或者使用 this 进行替代都可以(实际开发中一般直接省略),代码如下:


super 关键字省略:


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public void show(){ System.out.println("学生信息如下:姓名:"+getName()+",性别:"+ getSex()+"编号:"+getId()+",分数:"+this.studentScore); }
public void test2(){ System.out.println("调用父类方法"); test(); }}
复制代码


使用 this 关键字:


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public void show(){ System.out.println("学生信息如下:姓名:"+this.getName()+",性别:"+ this.getSex()+"编号:"+this.getId()+",分数:"+this.studentScore); }
public void test2(){ System.out.println("调用父类方法"); this.test(); }}
复制代码


应用三:调用父类构造方法:


子类在创建对象时需要使用构造方法,并且一定会使用父类的构造方法,我们来看看子类是如何调用父类的构造方法的?


父类:


package cn.hz;
/** * @author hz * @version 1.0 * 父类: 封装 */public class Person { private Integer id; //属性:学生编号 private String name; //属性:学生姓名 private String sex; //属性:学生性别
//set/get省略

public Person() {
}
public Person(String name) { this.name = name; }
public Person(Integer id, String name) { this.id = id; this.name = name; }
public Person(Integer id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; }}
复制代码


子类:


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public Student(Integer studentScore) { this.studentScore = studentScore; }
public Student(String name, Integer studentScore) { super(name); this.studentScore = studentScore; }
public Student(Integer id, String name, Integer studentScore) { super(id, name); this.studentScore = studentScore; }
public Student(Integer id, String name, String sex, Integer studentScore) { super(id, name, sex); this.studentScore = studentScore; }}
复制代码


通过上方代码我们可得调用父类的构造方法:


super(属性);
复制代码


注意,子类调用父类的构造方法时,同子类自己构造方法之间相互调用一样,该代码一定是在构造方法的第一行

3.案例分析:

案例一: 以下代码运行结果什么?


package cn.hz;
/** * @author hz * @version 1.0 * 父类: 封装 */public class Person { private Integer id; //属性:学生编号 private String name; //属性:学生姓名 private String sex; //属性:学生性别
//set/get省略

public Person() { System.out.println("父类无参方法"); }
public Person(String name) { this.name = name; System.out.println("父类name属性构造方法"); }
public Person(Integer id, String name) { this(); this.id = id; this.name = name; System.out.println("父类id,name属性构造方法"); }
}
复制代码


package cn.hz;
/** * @author hz * @version 1.0 */public class Student extends Person { public Integer studentScore; //属性:学生分数
public Student() { System.out.println("子类无参构造方法"); }
public Student(String name, Integer studentScore) { super(name); this.studentScore = studentScore; System.out.println("子类属性name构造方法"); }
public Student(Integer id, String name, Integer studentScore) { super(id, name); this.studentScore = studentScore; System.out.println("子类属性name,id构造方法"); }
}
复制代码


package cn.hz;
/** * @author hz * @version 1.0 */public class StudentTest { public static void main(String[] args) { //创建学生对象 Student student1=new Student();
//创建学生对象 Student student2=new Student("zs",80);
//创建学生对象 Student student3=new Student(10001,"ls",90); }}
复制代码


刚看到这个案例,可能很多同学感觉不知从何下手,本案例主要考察大家对对象创建过程的掌握及 super 和 this 关键字的熟练度,首先我们分析 student1 对象的创建,子类含有无参构造方法,虽然子类无参构造方法没有显式调用父类的构造方法,但是子类在创建对象时一定会调用调用父类构造方法,所以 student1 的创建会调用子类无参构造,父类无参构造;


student2 创建时会调用子类自己对应参数的构造方法,首行含有 super(name),则会调用父类对应的构造方法,父类中含有对应的构造方法则直接执行。


student3 创建时会调用子类对应的参数的构造方法,首行含有 super(id,name),则会调用父类对应的构造方法,父类中含有对应构造方法则执行,但是重点来了,在父类的构造方法中,首行出现了 this();这是很多同学容易出现错误的地方,this()表示父类调用自己的无参构造方法,则整个过程调用执行了三个构造方法,最终执行结果如下:



小结:
  • 子类调用父类的构造方法是,同子类自己构造方法之间相互调用一样,该代码一定位于构造方法第一行;

  • 子类构造方法中如果显式调用对应构造方法,则创建对象时先调用父类对应构造方法,则调用子类构造方法。

  • 子类构造方法中如果没有显式调用父类的构造方法,则默认调用父类的无参构造方法,子类创建对象时一定会调用父类的构造方法。

用户头像

加百利

关注

还未添加个人签名 2021.06.08 加入

还未添加个人简介

评论

发布
暂无评论
JAVA 面向对象 (十二)-- 关键字 super