一、继承
1、认识继承

创建父类 People ,里边包含有name和sex两个私有变量;创建子类Teacher(用关键字 extends把父类写在后面),里边包含skill私有成员变量。
继承后的子类不仅能访问自己类当中的变量,还能访问父类当中的变量。


2、权限修饰符
定义:用来限制类中的成员(成员变量、成员方法、构造器),能够访问的范围

(1)在本类中访问:这些权限修饰符都能在本类中被访问

(2)同包中其他类:同一包的其他类中,只是不能访问 private 私有
(3)子类中,因为是继承父类,所以可以直接调用父类中的方法而不用创建对象想要在其他包中继承另外一个包的父类,直接在上面将父类文件导入即可


3、继承的特点
(1)单继承、多层继承、祖宗类



如下,c 继承了 b,b 继承了 a,a默认继承了Object

(2)就近原则:优先访问自己类中,自己类中没有才会访问父类(对于变量和方法都一样的)
如下,在父类中定义来公开的成员变量 name,在子类中继承了父类,并且子类中也定义了自己的 name成员变量,而且子类中的方法中也定义了name变量在子类的方法中输出 name,有3个同名的 name ,依照就近原则,那么就是 子类方法中的name

局部变量和成员变量冲突,带上 this 的话那么就是访问的是 局部变量

想要访问父类中的变量,那么就在前面加上 super 即可


4、方法重写
(1)定义:
当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写




(2)方法重写在开发中常见的应用场景
- 子类重写 Object类 的 toString()方法,以便返回对象的内容
- 构造学生类
- 构造有参无参构造器
- get和set方法
- 创建对象给对象属性赋值
- 输出对象
直接打印中写 s对象 时,打印出来的是地址,于我们是无意义的,想看的是内容。那是因为在输出对象的时候调用的是 object 的 toString方法,并不是我们在 student对象中的方法,而是继承object的toString方法,只不过 toString可以省略不写- 在 student 子类中重写 toString 方法,怎么找到student类的父类 Object呢,左手ctrl键盘,右点击。


5、子类构造器的特点
(1)定义
子类的全部构造器,都会先调用父类的构造器,再执行自己
子类构造器是如何调用父类构造器的:
默认情况,子类全部构造器的第一行代码都是 super() (写不写都有),它会调用父类的无参数构造器
如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写 super(...),指定去调用父类的有参数构造器。
创建父类、子类,以及父类和子类各自的构造器
众所周知,在创建对象时,会调用类的构造器
这里要创建子类的对象,那么创建对象的话就会去调用子类构造器,但是由于子类还有继承父类,那么就会先去调用父类构造器,然后才调用子类构造器
如果是要调用的不是无参构造器而是有参构造器,那么就要在子类的构造器上写上 super(参数)指定调用父类的有参构造器
注意:子类的无参构造器一定调用的是父类的无参构造器,如果父类仅有有参构造器,那么就要在子类的 无参构造器里 第一行写上 super( 参数)。实际上每个构造器上第一行都是 super(),默认都是先调用父类无参构造器,但是如果没有父类无参,只有父类有参,那么就要在里边加上 参数了。


(2)子类构造器调用父类构造器的应用场景
Test2中创建 Teacher对象,创建对象时会调用 构造器赋值,去调用 Teacher子类的构造器时,但是子类有参构造器中的参数name和sex在父类中构造器才能完成赋值,那么就通过 super(name,sex)调用 People父类构造器为俩赋值。


(3)this(...)调用兄弟构造器
注意:super(...) this(...) 必须写在构造器第一行,且两者不能同时出现


二、多态
1、认识多态
(1)定义:多态是在继承 /实现(后面的内容)情况下的一种现象,表现为 :对象多态、行为多态

(2)对象多态:
父类引用子类对象,也就是父类变量指向子类对象,那个赋值操作。范围小的(子类对象)可以给范围大的(父类)。

(3)行为多态
也就是方法多态,父类子类中都有名称相同的方法(子类中进行了方法重写),那么调用创建好的父类型子类对象时,实际上运行的方法是子类中的方法,体现的就是行为多态。

(4)于成员变量不适用
基于上面的基本情况后,如果是输出变量的话,输出的是父类中的变量,所以变量就没有多态性

(5)多态的前提
有继承 / 实现关系;存在父类引用子类对象;存在方法重写
2.多态的好处
(1)右边对象是解耦合的

(2)多态的好处2:父类类型的变量作为参数,可以接收一个子类对象
- 定义 go 方法,形参是 Wolf w ,最后调用 wolf类中的 run 方法。
- 主程序中执行go方法,go中传入形参 w,执行到后面要调用run 方法时,跑到wolf 类中去调用。
- 注意:因为这里在定义 go 方法时,传入的形参已经写死,只能是 wolf 型的 变量 w,所以就只能传入 wolf 型的变量 w 了,因为也仅仅定义了 wolf 型的一个变量 w
- 如果想要每个动物都能传入进去而不仅仅针对其中一个动物,这该怎么办呢?

当用父类类型变量作为形参时,可以接收子类对象

- 一些类的方法是独有的 ,例如 wolf 对象中,狼吃羊。
- 那如下实例对象中,因为编译看左,左边是父类类型,所以实际 a1 调用该方法,实际是父类在调用,那么父类中又没有该方法,所以在编译过程就是直接报错了
- 同样,在方法中也没法调用,因为形参当中 既可以传入 wolf ,又可以传入Tortoise,而狼吃羊方法是 wolf 独有的,自然也就不能调用。

3.多态下的类型转换问题

强制类型转换

强制类型转换之前先判断 对象的真实类型


三、案例-加油站支付小模块

写 @Data之后按住 alt 键,然后按住 enter 键,那么就会自动导入

1、定义父类
card包里边写私有变量,以及一些公共方法,例如不管是金卡银卡都是要进行存储和消费的,那么就可以写这两个公共方法。

2、定义金卡类
完成金卡现在钱和支出钱的打印,并且还要完成自己独特的功能,判断是否能免费洗车,

3、定义银卡类
继承Card类:银卡必须重写消费方法(9折优惠)

4、创建金银卡对象
刚才仅是定义了金卡类,现在要创建金卡、银卡对象,交给一个独立业务来完成:存款、消费

5、支付机
用一个方法来刷卡:可能接收金卡,也可能接收银卡

