使用工具 IntelliJ IDEA Community Edition 2023.1.4
使用语言 Java1.8
1.初识继承
利用Java继承的特性可以根据业务需求将相同的属性和行为提取出来,抽象成一个新的类,这样就避免了代码冗(rong)余,也方便进行扩展。
1.1 继承的基本概念
1.1.1 基本概念
- 继承是面向对象三大特性之一,封装也是其一,还有一个多态在后面讲解,继承可以解决编程中代码冗余的问题,是实现代码重用的重要手段之一。(如果有多个用法名字相同但有一个类没有的属性就可以用继承而不用考虑那个没有该属性的类,只要不在它那边引用即可)
- 继承是软件可重用性的一种表现,使子类具有父类相同的特征和行为,从而缩短开发周期。
- 此时新类被称为子类,现有的类被称为父类。Java语言通过extends关键字实现类之间的继承关系。继承最基本的作用就是使代码可重用,增加软件的可扩展性。
1.1.2 继承的语法
[访问修饰符] class <SubClass> extends <SuperClass>{
...
}
其中,SubClass被称为子类或派生类,SuperClass被称为父类或基类。在Java中,继承的规则如下:
- 可以继承父类中public和protected修饰的属性和方法,不论子类和父类是否在一个包中;
- 可以继承默认访问修饰符修饰的属性和方法,但是子类和父类必须在同一个包中;
- 无法继承private修饰的属性和方法;
- 无法继承父类的构造方法;
在Java中只支持单继承,即每个类只能有一个直接父类;
1.2 继承的应用
- 在提取过程中,公共方法中调用非公共属性的语句需要稍作调整,如果不是公共属性,在父类中不包含,会出现编译错误,子类中不是公共属性且父类中没有的属性在子类无法使用;
- 可以使用super关键字调用父类的构造方法或父类属性(super关键字将在后面进行详细讲解);
- 创建子类对象后,可以用子类对象调用父类的方法,这样是使用继承父类的对应方法;
1.3 Object类
1.3.1 Object类继承基本概念
所有的Java类都直接或间接地继承Object类,它位于Java.lang包中。Object类是所有Java类的"祖先"。在定义一个类时,没有使用extends关键字,也就是没有显示地继承某个类,那么这个类直接继承Object类。所有对象都继承Object类的方法。
1.3.2 Object类的常用方法
toString() | 返回当前对象本身的有关信息,返回字符串对象 |
boolean equals() | 比较两个对象是否是同一个对象,若是,则返回true |
Java.lang.String类重写了Object类中的equals()方法 | |
Object clone() | 生成当前对象的一个副本,并返回 |
int hashCode() | 返回该对象的哈希代码值 |
getClass() | 获取当前对象所属的类信息,返回Class对象,即运行时类 |
2.继承关系中的方法重写
子类通过继承可以拥有和父类相同的特征和行为,另外,子类也可以根据需要,定义自己特有的行为,即沿袭了父类的方法名称,又重新实现了父类方法,这就是方法重写。
2.1 方法重写
如果父类继承的方法不能满足子类的需求,则可以在子类中对父类的同名方法进行重写(覆盖),以符合需求。
2.1.1 方法重写基本概念
就是在子类中新建一个与调用的方法名同样的方法名,然后在里面填上super.原来的父类方法(),然后后面再跟需要添加的内容即可,也可以不添加super调用父类方法(逻辑是先调用父类的对应方法,之后再执行下面的方法体部分/不添加就是调用子类对应方法时会调用子类重写的方法)。
在子类中可以根据需求对从父类继承的方法进行重新编写,这被称为方法重写或方法覆盖,方法重写必须遵守以下规则:
- 重写方法和被重写方法必须具具有相同的方法名;
- 重写方法和被重写方法必须具有相同的参数列表;
- 重写方法的返回值类型必须和被重写方法的返回值类型相同或是其子类(代表要么是相同的返回值类型,要么是那个返回值类型的子类返回值类型);
- 重写方法不能缩小被重写方法的访问权限;
2.1.2 自动添加重写
另外,idea工具提供了便捷的方式方式来实现对父类方法的重写操作,步骤如下:
- 右击页面代码部分,在打开的列表中选择"生成";
- 单击"重写方法"选项;
这里列出了所有运行在子类中进行重写的父类方法,包括顶级父类Object类中定义的方法。选择重写的方法,默认勾选"Insert@Override"复选框,单击"OK"按钮即可。
2.1.3 Java重写注解
@Override是用Java注解的方法表示该方法重写了父类方法,可以写也可以不写,在功能实现上没有区别,都是通过@Override注解,程序更加方便阅读。另外,编译器也会帮助验证@Override下面的方法名是否是父类所有的。如果不符合方法重写规则,则会报错。
Java注解又被称为Java标注,是Java5引入的一种注释机制。Java注解属于Java技术的进阶内容,在本篇文章中不详细讲解,可通过查阅网络资料稍作了解。
2.1.4 Java重写标志
一个圆环加一个向上箭头代表重写父类的方法,同样在重写父类的对应父类方法部分也会出现一个圆环加向下箭头,表示这个方法在子类中被重写
2.2 super关键字
super关键字代表对当前对象的直接父类对象的默认引用。在子类中可以通过super关键字访问父类的成员,包括父类的属性和方法。
2.2.1 super关键字的语法
访问父类构造方法: super(参数)
访问父类属性/方法: super.<父类属性/方法>
2.2.2 使用super关键字时注意
- super关键字必须出现在子类(子类的方法和构造方法)中,而不允许出现在其他位置;
- 可以访问父类的成员,如父类的属性、方法、构造方法;
- 注意访问权限的限制,如无法通过super关键字访问private成员;
- 在构造方法中如果有this语句或super语句,则只能是第一条语句;
- 在一个构造方法中,不允许同时使用this关键字和super关键字调用构造方法(否则就有两条第一条语句);
- 在静态方法中不允许出现this关键字或super关键字;
- 在实例方法中,this语句和super语句不要求是第一条语句,可以共存;
2.3 继承关系中的构造方法
2.3.1 Java中的构造方法会在什么情况下被执行
在Java中,一个类的构造方法在如下两种情况下会被执行。
- 创建该类的对象(实例化);
- 创建该类的子类的对象(子类的实例化);
子类在实例化时,会首先执行父类的构造方法,然后才会执行子类的构造方法
2.3.2 Java类继承后构造方法执行顺序(多级继承)
在Java语言中,当创建一个对象时Java虚拟机会按照父类-子类的顺序执行一系列的构造方法。子类继承父类时构造方法的调用规则如下:
- 如果在类的构造方法中没有通过super关键字显式调用父类的带参构造方法,也没有通过this关键字显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,是否写"super();"语句,效果是一样的;
- 如果在子类的构造方法中通过super关键字显式地调用了父类的带参构造方法,那么将执行父类相应的构造方法,而不执行父类无参构造方法;
- 如果在子类的构造方法中通过this关键字显式地调用了自身的其他构造方法,那么在相应构造方法中遵循以上两条规则;
- 如果存在多级继承关系,则在创建一个子类对象时,以上规则会多次向更高一级父类应用,直到执行顶级父类Object类的无参构造方法为止;
实例化后会依次向上一级父类调用构造方法,最后调用Object的无参构造方法(该方法内容为空),执行构造方法的顺序与其相反,是从Object开始
如果不用super关键字显式调用父类带参构造方法,将默认调用父类无参构造方法
2.3.3 Java继承关系中的构造方法总结
如果类存在多级继承关系,则在创建一个子类对象时,构造方法的调用规则会多次向更高一级父类传递,一直到执行顶级父类Object类的无参构造方法为止;
子类的构造方法默认调用父类无参构造方法,在这种情况下,无论是否使用super()语句,执行结果都相同;