我们在创建对象时都会有一个模板,这个模板叫做类。
如果有多个类里有相同的属性或者方法(这里的属性和方法并不是指完全一样的,只要功能相同也是可以的),都可以实现某种功能。
例如:
class Phone{//手机
public String color;//颜色
public void playGame(){//玩游戏
System.out.println("玩游戏");
}
}
class RecreationalMachine{//游戏机
public String color;//颜色
public void playGame(){//玩游戏
System.out.println("玩游戏");
}
}
这里有两个类:手机类和游戏机类,一般来说:他们具有相同的属性(颜色)和方法、功能(玩游戏)。我们则可以把这些相同的属性或方法、功能整理并提出,构成一个新的类,这个类可以叫做这两个类的父类,也可以说是什么(子类)是什么(父类),只要满足这种语法结构的,都是可以继承的。例如:手机是游戏机器,游戏机是游戏机器。
父类如下:
public class GameMachine {//游戏机器
public String color;
public void playGame() {
System.out.println("玩游戏");
};
}
如果有这样的一个父类,那么在创建手机类和游戏机类时,就可以这样写(这里在Phone类中新建了一个call方法,子类中可以有特殊方法):
public class GameMachine {//游戏机器
public String color;
public void playGame() {
System.out.println("玩游戏");
};
}
class Phone extends GameMachine{//手机
public void call(){
}
}
class RecreationalMachines extends GameMachine{//游戏机
}
这里的手机和游戏机类就可以继承游戏机器类里的color成员变量(属性)和playGame成员方法,语法格式为:
[修饰符列表] 类名 extends 父类
class Test{
public static void main(String[] args) {
Phone a = new Phone();
RecreationalMachines b = new RecreationalMachines();
a.playGame();
b.playGame();
}
}
此时a和b调用的是父类中playGame()方法,当然如果方法在子类中无法满足其要求,那么我们也可以选择在他们各自的类体中重写playGame()方法,此时父类中的playGame()方法被覆盖,这样在调用方法时,会调用子类中的playGame()方法,如果想要在对象中调用父类的方法,则需要用super来调用父类中被覆盖的方法,语法为super.方法名,并将这个语句放在一个方法中便可以调用父类方法。
class Phone extends GameMachine{//手机
public void playGame(){
System.out.println("玩手机游戏");
super.playGame();
}
public void call(){
}
}
class RecreationalMachines extends GameMachine{
public void playGame(){
System.out.println("玩游戏机游戏");
}
}
结果为:
玩手机游戏
玩游戏
玩游戏机游戏
super关键字
super可以调用父类的属性,成员方法以及构造方法,由于子类在继承时只能继承父类中的非私有属性和方法,所以子类使用super也只能调用可以继承父类的那一部分
在子类的构造方法中如果没有使用super关键字调用父类的构造方法,那么Java会默认在子类的构造方法的第一行加上super();来调用父类的无参构造方法。我们都知道构造方法的作用是用来初始化成对象的,但是我们知道这里如果调用了父类的构造方法时并不是创建了一个父类的对象,而是对父类的成员变量进行了初始化,所以这就是为什么会在子类的构造方法的第一行取调用父类的构造方法,如果不先对父类的成员变量进行初始化,那么子类也就无法使用父类中的属性和方法。所以在子类的构造方法的第一行必须先调用父类的构造方法,如果想调用父类的有参构造方法,那么我们也可以使用super(参数列表);来调用父类的有参构造方法。
super.属性名也可以调用父类的成员变量,当子类和父类的成员变量具有相同的名字时,我们也可以使用super.属性名来区分父类的成员变量和子类的成员变量
super.方法名可以调用父类的方法,如果子类中没有重写父类的该方法,那么调用方法时也可以不加super直接调用父类方法。子类在重写父类的方法时如果还想使用父类的该方法是不需要将父类方法的调用放在重写方法的第一行的,因为在子类调用构造方法时已经对父类进行初始化,所以父类的方法在哪里使用就在哪里调用即可。