1.继承的好处
继承可以使子类继承父类的非私有属性,提高了代码的复用性。如下:
//老师和学生都属于人,都有姓名和年龄属性,可以抽取到人这个类里面再给老师和同学继承。
public class People {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//学生类,有自己的私有方法学习
public class Student extends People {
public void study() {
System.out.println("键盘敲烂,月薪过万");
}
}
//老师类 有自己的方法上课
public class Teacher extends People {
public void teach() {
System.out.println("传道受业解惑");
}
}
2.继承的特点
-
子类可以继承父类非私有的属性和方法,包括静态方法,但是不能继承构造器!
-
Java是单继承模式:一个类只能继承一个直接父类,,Java不支持多继承、但是支持多层继承
-
Java中所有的类都是Object类的子类
-
子类方法中访问成员(属性、行为)的特点:现在子类局部范围找,找不到到成员范围找,再找不到就到父类成员范围找,还没找到就会报错
3.方法的重写
3.1方法重写的条件
子类和父类有一模一样的方法声明,当父类的方法只能满足子类的一部分的需求的时候,就可以使用方法的重写,实现其他的需求,注意父类的静态方法和私有方法不能被重写
3.2方法重写的实现
//手机类
public class Phone {
//旧手机类只有打电话和发短信两个功能
//打电话
public void call() {
System.out.println("嘟嘟嘟~~~喂?小丽呀!!!");
}
//发短信
public void sendMessage() {
System.out.println("发送短信:夜已深,你寂寞吗?");
}
//父类私有方法
private void keyboard() {
System.out.println("键盘敲击得飞起!");
}
//父类默认方法
protected void playGame() {
System.out.println("手机游戏真好玩!");
}
//父类静态方法
public static void gps() {
System.out.println("使用了卫星gps定位系统!");
}
//新手机类
public class NewPhone extends Phone {
@Override
public void call() {
//重写方法的第一件事是利用super关键字调用父类的同名方法已实现现有的功能
super.call();
//之后再继续实现自己需要的功能
System.out.println("视频通话");
}
@Override
//发短信
public void sendMessage() {
System.out.println("发送短信:夜已深,你寂寞吗?");
}
//父类私有方法
private void keyboard() {
System.out.println("键盘敲击得飞起!");
}
@Override
//父类默认方法
//重写之后子类的访问权限必须大于父类
protected void playGame() {
System.out.println("手机游戏真好玩!");
}
//@Override
//父类静态方法
//静态方法不能被重写
public static void gps() {
System.out.println("使用了卫星gps定位系统!");
}
}
4.子类继承父类后构造器的特点
特点:子类中所有的构造器默认都会先访问父类中无参的构造器,再执行自己
原因:子类会继承父类属性,如果子类初始化时要使用父类属性,父类没有完成初始化,就用不了
调用父类构造器:子类构造器第一行默认都是super(),不写也存在
父类的构造方法先于子类的构造方法执行,就算使用子类的有参构造也只会执行父类的无参构造
4.1子类构造中调用父类满参构造的示例
//手机父类
public class Phone {
private String brand;
private int price;
public Phone() {
}
public Phone(String brand, int price) {
this.brand = brand;
this.price = price;
}
//手机子类
public class NewPhone extends Phone{
private int size;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public NewPhone() {
}
public NewPhone(String brand, int price) {
//使用this(参数)在子类非满参的构造方法里面调用满参构造函数
//目的是给这个构造方法没有给初始值的成员属性值赋初始值
this(brand, price, 6);
}
public NewPhone(String brand, int price, int size) {
//先使用super关键字super(参数)方法调用父类满参构造来初始化值,这些初始化的值
//其实也被子类继承了。
super(brand, price);
this.size = size;
}
}
4.2当父类只有满参构造函数
解决方案:
- 父类加空参构造
- 子类使用super(参数)手动调用父类有参构造