Java super用法详解
在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。
需要注意的是,在子类中重写的方法需要和父类中被重写的方法具有相同的方法名、参数列表及返回值类型。
【实例】重写继承的方法。
关键字 super 可用于访问父类中的构造方法、属性和方法。下面介绍关键字 super 的具体用法:
下面通过一个实例来介绍使用关键字 super 访问父类的属性和方法。
由运行结果可知,子类通过关键字 super 可以成功地访问父类的成员变量和成员方法。
实际上,当父类中有无参构造方法时,编译器默认在子类的所有构造方法中的第一行自动添加 super() 方法,隐式调用父类的无参构造方法。
【实例】隐式调用父类的构造方法。
构造方法的规则包括以下几点:
需要注意的是,在子类中重写的方法需要和父类中被重写的方法具有相同的方法名、参数列表及返回值类型。
【实例】重写继承的方法。
class Human {
// 定义人类吃东西的方法
void eat() {
System.out.println("人类吃东西");
}
}
// 定义 Sportsman 类继承 Human 类
class Sportsman extends Human {
// 重写 eat() 方法
void eat() {
System.out.println("运动员吃健身餐");
}
}
// 定义测试类
public class Test {
public static void main(String[] args) {
// 创建一个 Sportsman 实例对象
Sportsman s = new Sportsman();
// 调用 s 对象重写的 eat() 方法
s.eat();
}
}
运行结果为:
运动员吃健身餐
由实例的运行结果可知,当子类重写父类的方法后,子类对象将无法访问父类被重写的方法。如果在子类中访问父类的被隐藏的属性和重写的方法,那么需要使用关键字 super。关键字 super 可用于访问父类中的构造方法、属性和方法。下面介绍关键字 super 的具体用法:
//访问父类的构造方法 super(参数列表) //访问父类的属性 super.属性 //访问父类的方法 super.方法名()下面通过一个实例来介绍 super() 方法的应用。
/**
* 定义父类 Human2
*/
class Human2 {
// 使用构造方法初始化属性 meal
public String meal;
Human2(String meal) {
this.meal = meal;
System.out.println("人类吃" + meal);
}
}
/**
* 定义子类 Sportsman2
*/
class Sportsman2 extends Human2 {
// 子类的构造方法通过关键字 super 调用父类的构造方法,并传递参数
// 此处必须调用,否则编译报错
Sportsman2(String meal) {
super(meal);
System.out.println("运动员吃东西");
}
}
public class Test {
public static void main(String[] args) {
// 子类实例化,调用父类和子类的构造方法
Sportsman2 b = new Sportsman2("早餐");
}
}
运行结果为:
人类吃早餐
运动员吃东西
下面通过一个实例来介绍使用关键字 super 访问父类的属性和方法。
class Human3 {
String name = "人类";
// 定义人类吃东西的方法
void eat() {
System.out.println("人类吃东西");
}
}
// 定义 Sportsman3 类继承 Human3 类
class Sportsman3 extends Human3 {
String name = "一个人"; // 子类可以有自己的属性,这里覆盖了父类的属性
// 重写 eat() 方法
void eat() {
// 访问父类的成员方法
super.eat();
// 这里可以添加运动员特有的吃东西行为
}
// 定义打印 name 的方法
void printName() {
// 访问父类的成员变量
System.out.println("name = " + super.name);
}
}
public class Test {
public static void main(String[] args) {
// 创建一个 Sportsman3 实例对象
Sportsman3 x = new Sportsman3();
// 调用 x 对象重写的 eat() 方法
x.eat();
// 调用 x 对象的 printName() 方法
x.printName();
}
}
运行结果为:
人类吃东西
name = 人类
由运行结果可知,子类通过关键字 super 可以成功地访问父类的成员变量和成员方法。
实际上,当父类中有无参构造方法时,编译器默认在子类的所有构造方法中的第一行自动添加 super() 方法,隐式调用父类的无参构造方法。
【实例】隐式调用父类的构造方法。
/**
* 定义父类 Human4
*/
class Human4 {
public int a;
// 定义无参构造方法
Human4() {
System.out.println("人类吃东西");
}
// 构造方法,初始化 a
Human4(int eat) {
this.a = eat;
}
}
/**
* 定义 Sportsman4 类
*/
class Sportsman4 extends Human4 {
// 可以不写父类的构造方法的调用,默认隐式调用父类的无参构造方法
Sportsman4() {
System.out.println("运动员吃东西");
}
}
public class Test {
public static void main(String[] args) {
// 创建 Sportsman4 的实例
Sportsman4 b = new Sportsman4();
}
}
运行结果为:
人类吃东西
运动员吃东西
class Sportsman4 extends Human4 {
Sportsman4() {
super(); // 隐含了这行代码
System.out.println("运动员吃东西");
}
}
假如 Sportsman4 类的构造方法没有参数,并且只调用 Human4 类的无参构造方法,正如上面例子所示,那么子类的构造方法也可以省略不写,如下所示:
class Sportsman4 extends Human4 {
}
如果执行上面的代码,实际上就是编译器默认添加了 Sportsman4 类的无参构造方法,并且在其中调用了 Human4 类的无参构造方法。但是,如果父类没有无参构造方法,那么在子类中必须使用关键字 super 显式调用父类的有参构造方法。这种隐式调用的方式使用得比较多,为了方便继承,在设计父类时都会提供一个无参构造方法。构造方法的规则包括以下几点:
- 如果一个类中没有声明任何构造方法,那么编译器默认为该类添加一个无参的、空方法体的构造方法;
- 如果一个类中已声明有参构造方法,那么编译器不再默认添加无参构造方法;
- 如果一个构造方法的第一行没有显式声明语句 this(); 或 super();,那么编译器会自动添加 super(); 语句,隐式调用父类的无参构造方法。
ICP备案:
公安联网备案: