继承

继承

[TOC]

面向对象三大特征:封装、继承、多态

  1. 封装:对象代表什么,就得封装对应的数据,并且提供数据对应的行为

继承

在java当中,提供了一个关键字:extends ,使用这个关键字可以让一个类与另一个类建立起继承关系。

栗子:

1
public class Student extendes Person{};

上面的代码中:Student称为子类(派生类),Person称为父类(基类或者超类)。

使用继承的好处:

  • 可以把多个子类中重复的代码抽取到父类当中,提高了代码的复用性
  • 子类可以在父类的基础上,增加其他的功能,使得子类更加强大。

自己设计

什么时候会用到继承:当类与类之间,存在相同(共性)的内容,并且满足子类是父类其中的一种是,就可以考虑使用继承。

比如:

学生 老师
姓名 姓名
年龄 年龄
性别 性别
学习 教书

可以看到学生和老师都有姓名、年龄、性别这几个属性。那么就可以把这几个属性提取出来,放到父类里面。

继承中的特点

一句话概括:java只支持单继承,不支持多继承,但是支持多层继承

  • 单继承:一个子类只能继承一个父类(一个儿子只能有一个父亲)
  • 不支持多继承:子类不能同时继承多个父类(一个儿子不同同时有多个父亲)
  • 多层继承:子类A可以继承父类B,父类B可以继承父类C,父类C是子类A的间接父类

java中有一个类是所有类的祖宗:Object。java中的每一个类都直接或者间接继承于Object。

注意:子类只能访问父类中非私有的成员。

继承可以继承父类中哪些内容

父类中会有以下三种东西:

  1. 构造方法
  2. 成员变量
  3. 成员方法

根据其中是否私有,可以继承的情况分下面几类:

非私有是否能继承 私有是否能继承
构造方法 不能 不能
成员变量
成员方法 // //

其中成员方法:只有能够添加到虚方法表中的方法才能被继承。也就是说除了private、final、static修饰的方法,都可以被继承。

继承中成员变量访问特点

就近原则:谁离我近,我就用谁

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Fu(){
String name = "Fu";
}

public class Zi extends Fu(){
String name = "Zi";
public void ziShow(){
String name = "ziShow";
System.out.println(name); // "ziShow"(从局部位置开始往上找)
System.out.println(this.name); // "Zi"(从本类成员位置开始往上找)
System.out.println(super.name); // "Fu"(从父类成员位置开始往上找)
}
}

先在局部位置找,本类成员位置找,父类成员位置找,逐级往上。

继承中成员方法的访问特点

直接调用满足就近原则:谁离我近,我就用谁

super关键字

用来显示访问父类成员或者构造方法。

super调用:直接访问父类。

可以使用supper.父类方法来调用父类的方法;可以使用super.父类属性来调用父类的属性。

调用父类的构造方法:

在子类中使用够惨构造方法,在方法里面使用super(父类的参数)

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args){
Student s = new Student();
s.lunch();
// 吃饭
// 喝水
}

class Person{
public void eat(){
System.out.println("吃饭");
}

public void drink(){
System.out.println("喝水");
}
}

class Student extends Perdson{
public void lunch(){
eat();
drink();
}
}

同样的如果调用方法时,前面加了super,那么就会直接去调用父类的方法。
前面加了this,就会调用本类的方法。

方法的重写

当父类的方法不能满足子类现在的需求时,就需要进行方法的重写。

书写格式:

在继承体系中,子类出现了和父类一模一样的方法声明,我们就称子类的这个方法是重写的方法。

  • @Override 重写注解
    1. @Override 是放在重写后的方法上,用来校验子类重写是语法是否正确。
    2. 加上注解之后如果有红色的波浪线,表示语法错误。
    3. 建议重写方法都加@Override注解,代码安全优雅

如果在子类重写了方法,那么这个方法就会覆盖掉父类的方法。

方法重写注意事项与要求

  1. 重写方法的名称、形参列表必须与父类当中的一致。
  2. 子类重写父类方法时,访问权限子类必须大于等于父类。(空着不写 < protected < public)
  3. 子类重写父类方法时,返回值类型子类必须小于等于父类。(了解)
    比如: 父类为animal 子类为cat和dog:那么子类返回的范围就不能不animal还大
  4. 重写的方法尽量与父类保持一致
  5. 只有添加到虚方法表的方法才能被重写。

方法重写的本质:

覆盖虚方法表中的方法

继承中构造方法的特点

  • 父类中的构造方法不会被子类继承
  • 子类当中所有的构造方法都会先默认访问父类中的无参构造,再执行自己。
    为什么呢?
    - 因为子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
    - 子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
    怎么调用父类构造方法?
    - 子类构造方法的第一行语句默认都是:super(),不写它也在,并且必须在第一行。
    - 如果想调用父类有参构造,必须手动写super进行调用

this,super总结

  • this可以理解为一个变量,里面存着当前方法调用者的地址值。
  • super表示父类的存储空间
关键字 访问成员变量 访问成员方法 访问构造方法
this this.成员变量 访问本类成员变量 this.成员方法(…) 访问本类成员方法 this(…) 访问本类方法
super super.成员变量 访问父类成员变量 super.成员方法(…) 访问父类的成员方法 super(…) 访问父类的构造方法