什么叫继承?
子类(this)继承父类(super)的因素(成员变量和方法) 子类继承父类的特征 一个子类只能继承一个父类 一个父类可以被多个子类所继承,子类具有可拓展性,继承提高了代码的可重复利用性
- Java中提供一个关键字 extends 用这个关键字可以让一个类继承另一个类建立起父子关系。
- 例如子类 学生类(派生类/子类) 父类为人类 (基类/超类/父类)
- 作用:子类继承父类后 子类可以使用父类的公共的属性和方法
可以看到:我们可以将相同重复的代码放在父类,然后在将自己独有的方法属性放在子类里面。
例如:老师、学生 都属于人类
小结:
- 继承就是Java允许我们用extends关键字,让一个类和另一个类建立一种父子关系
- 提高代码的复用性,减少代码的冗余,增强类的功能扩展性
- 子类 extends 父类
- 子类继承父类 子类可以得到父类的属性和行为 子类可以使用
- Java中子类更强大(扩拓展性)
继承:
- 子类相同特征(共用方法、属性)放在父类中定义 子类独有的属性和方法放在子类自己里面
- 如果子类的独有属性,行为放在父类中 会导致其他子类也会具有该种属型,不符合面向对象
当子类继承有一个父类,且创建一个子类对象后 这个对象分为(父类空间、子列空间)都指向一个对象。 super+this getter()、setter()......
继承的特点:
- 子类可以继承父类的属性和行为,但是子类不能继承父类的构造器
- Java是单继承模式,一个类仅仅只能继承一个父类
- Java不支持多继承的模式:假设多继承时父类中的方法相同时子类对象调用无法判断使用方法
- Java支持多层继承 儿子->父亲->爷爷....子子孙孙、无穷尽也
- Java中的所有的类都是Object的子类
注意事项:
子类是否可以继承父类的构造器?
不可以,子类有自己的构造器,父类构造器适用于初始化父类对象 不能交换构造权利!
子类是否可以继承父类的私有成员?
可以,但是不能访问!!!
争议点:
子类是否可以继承父类的静态成员?不能 静态的数据 不管是变量还是方法都是可以使用类名.(变量/方法)访问的 支持共享
显然:共享!=继承(需要满足父子关系)
子类可使用父类静态东西 但是:绝非继承!!!
注意事项:
在子类方法中访问成员(成员变量、成员方法) 满足:就近原则
- 先在子类局部范围查找
- 然后到子类成员范围查找
- 然后到父类成员范围找,如果父类范围还没找到就直接报错
如果子父类,出现了重名的成员,会优先使用子类自身的,此时如果一定要在子类中使用父类怎么办?
使用super关键字 指定访问父类的成员
格式:super.父类方法名/父类成员变量 需要在子类里面写,才能访问父类数据
<方法重写> 在父类的基础上继续增加功能
在子类方法中访问成员(变量和方法)满足:
- 就近原则,子类没有找子类 、子类没有找父类 父类没找到就保错!!!
如果子父类中出现了重名的成员,此时如果一定要在子类中使用父类怎么办呢?
- 在子类中写super.(成员变量/成员方法)
什么是方法重写?
- 在继承的体系中,子类出现了和父类一样的方法申明,我们称这个方法是重写的方法
方法重写场景:
- 当子类需要父类的功能,单父类的该功能不完全满足自己的需求可以累计迭代
- 子类可以重写父类的方法 子类里同方法名写super.方法名 继承父类方法+自己子类补充
案例:
旧手机功能:打电话、发信息
新手机:在旧手机的基础上 可以使用视频通话 可以发图片和音频
@Override 重写方法校验 + 子类需要重写的方法必须和父类对应的方法一模一样!!!
特点:子类的全部构造器默认先会访问父类的无参构造器 (先有父亲后有儿子)
注意事项:
子类继承后构造器的特点:
- 子类中所有的构造器默认先访问父类的无参构造器
为什么?
- 子类在初始化的时候,有可能用到父类的数据 所以要提前让父类初始化
- 子类初始化之前,一定要调用父类构造器先完成父类数据的初始化
怎么调用父类构造器?
- 子类构造器第一行默认有super() 不写也存在
利用父类的有参构造器初始化对象的数据:
注意事项:
super调用父类有参构造器的作用:
- 初始化继承自父类的数据
如果父类中没有无参构造器,只有有参构造器,会出现什么现象呢?
- 因为创建对象时,如果有继承的父类 他会先访问父类的无参构造器初始化再轮到自己。
- 如果父类没有无参构造器,则会报错!!! 所以必须要对父类定义构造器和各个方法。
解决方法?
- 子类构造器(必须是有参构造器!!!)里写: super(初始化数据) 手动调用。
this和super详情:
- this代表本类对象的引用 ; super代表父类对象的引用 (以下表格内容都在子类里面写)
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
this | this.成员变量 访问本类成员变量 | this.方法 访问本类成员方法 | this(...) 访问本类构造器 |
super | super.成员变量 | super方法 访问父类成员方法 | super(...) 访问父类构造器 |
至此我们就差this(...) 没有应用过了,接下来看看他的内容:
this()主要设置默认值 在构造器里面写 this(...)相当于兄弟构造器
this(...)和super(...)使用注意点:
- 子类通过this(...)去调用本类的其他构造器 本类其他构造器会通过super去手动调用父类构造器
- 注意:this(...)、super(...都只能放在构造器的第一行 、并且 二者不能位于同一个构造器里
包:
- 包是用来分门别类的管理各种不同类,类似于文件夹,建包利于程序的管理和维护。
- 建包的语法格式:package公司域名倒写.技术名称。报名建议全部英文小写,有意义。
例如:package com.cqie.javabean;
下面的语句-表述类
- 建包语句必须在第一行,一般IDEA根据会帮助创建
导包
- 相同包下的类可以直接访问,不同包下的类才需要导包操作。 导包格式:import 包名.类名;
- 假如一个类中需要用到不同类而这两个类的名称是一样的,默认导入一个类,另一个全名导入
权限设置修饰符:
- 权限修饰符:用来控制一个成员能否被访问的范围
- 可以修饰成员变量、方法、构造器、内部类、不同修饰符修饰的成员能够被访问的范围将受到限制
权限修饰符分类和具体作用范围:
- 权限修饰符:有四种作用范围从大到小:public>protected>缺省>private
- 调用方法前先创建对象 实例化调用方法即可
privarte: 在同一个类可以访问
缺省:同一个类或者同一个包下可以访问
protected:同一个类或者同一个包下或者不同包下的子类里面需要继承)可以访问
public: 以上三种外加不同包下的无关类
定义成员(方法,成员变量,构造器等)满足如下条件:
- 成员变量私有化满足Javabean封装
- 方法一般公开
- 如果该成员只希望本类访问,使用private修饰
- 如果该成员只希望本类,同一个包下和其他子类访问,使用protected修饰
final的作用:
- final关键字是最终的意思,可以修饰(类,方法,变量)在类型前加 修饰符后加
- 修饰类,使其不能被继承 绝育操作
- 修饰方法:方法不能被重写
- 修饰变量:变量的值有且只能被赋值一次
回忆之前的工具类:里面私有构造器 定义静态方法(验证码的例子)可以在方法类型前加final不能对该方法重写(变量分为:局部变量和成员变量(静态变量,实例变量))
注意:
final修饰变量有且只能赋值一次,对于引用类型来说使用final 不能约束成员变量的赋值情况
final修饰变量的注意事项:
- final修饰的是变量是基本类型,那么数据值不能发生改变
- final修饰的是变量是引用类型,变量存储的地址不会改变,但是地址指向的对象方法可以改变
常量:
- 常量是使用public static final修饰的变量,必须初始化,执行的过程中不能被改变
- 常量的作用和好处,可以做系统的配置系统,方便程序维护,提高代码的可读性 关联性
常量命名规则:
英文单词大写,多个单词使用_下划线连接
常量的执行原理:
- 编译阶段会进行宏替换(常量变为字面量)
- 这样做的好处是让使用常量的程序执行性能与直接使用的字面量一样
拓展:信号标志
假设我们要做一个游戏,用户按上下左右,调用对应的函数实现,我们可以使用常量做信息标志
先定义常量然后关联程序流程实现效果,可以构造一个公开的静态方法,然后结合switch值匹配。
枚举的概述:
- 枚举是Java中的一种特殊类型
- 其作用:为了做信息标志和信息分类
定义枚举类的格式:
修饰符 enum 枚举名称{
实例名称
}
枚举的特征:
- 枚举类都继承了枚举类型:java.lang.Enum
- 枚举都是最终类,不能被继承
- 构造器都是构造器私有的,枚举不能创建对象
枚举做信息标志和分类:
代码可读性好,入参约束谨慎,代码优雅,是最好的信息分类技术 关联:Orientation o
抽象类:
- 在Java中abstract是抽象的意思,可以修饰类和方法,与finnal互斥
- abstract修饰类,这个类就是抽象类;修饰方法,即是抽象方法
修饰符 abstract 方法类型 类名{
修饰符 abstract 返回值类型 方法名 (形参列表);
}
注意事项:
- 抽象的方法只有方法签名,不能声明方法体 不能写{}
- 一个类如果定义了抽象方法必须写抽象类,否则报错
抽象类的使用场景:
- 抽象类可以理解成不完整的设计图,一般作为父类,让子类完善重写方法
- 当父类知道子类一定要完成某些行为,但是子类的方法不同(将设计方法权限给子类自己)
- 抽象类由实现类实现
小结:
1、抽象类,抽象方法是怎样的?
- 都是abstract修饰,抽象方法只有方法签名,不能写方法体
- 一个类定义了抽象方法,这个类必须为抽象类
2、抽象类基本作用?
- 作为父类,用来被继承 实现类继承抽象类
3、继承抽象类有哪些要注意的?
- 实现类继承抽象类必须要方法重写所有抽象方法 否则这个类必须定义为抽象类
案例分析:
某健身房,一种是预存1000金卡(8折优惠),另一种是预存100的银卡(9折优惠)
请分别实现两种卡片进入收银系统后的逻辑,卡片包括主人明名称、余额、支付功能
补充:
类具有的东西,抽象类都有。
抽象类可以没有抽象方法,但是,抽象方法必须在抽象类里。
一个类(实现类)继承了抽象类,必须重写抽象类的全部方法,否则这个类定义为抽象类。
不能使用abstract修饰变量、代码块、构造器。
最重要的特征:得到了抽象方法,失去了创建对象的能力(实现类继承抽象类方法重写)
final和abstract是什么关系?
- 互斥关系
- abstract定义的抽象类模板让子类继承,final定义的类不能被继承
- 抽象方法定义通过功能让子类重写,final定义的方法不能重写
什么的时候使用模板方法模式:
场景:当系统中出现同一功能,而该功能大多一样,一种部分可能不同时。
模板方法的步骤:
- 将模板方法放在抽象类里先写好
- 模板方法中不能决定具体功能的部分(不同的部分),在抽实现类里写明(子类)方法重写
案例:写作文
需求:两类学生一类大学本科生,另一类研究生,现在需要两类学生完成一篇编程知识的文章。开始和结尾部分内容必须一样,中间内容任意发挥。选择最优的面向对象方案设计。
方法模板:
实现代码的复用性,写好抽象类,再子类里写好不同的方法,写一个函数在里面调用这个抽象类,关联,最终达到我们想要的。模板方法最好添加final修饰,使得模版(相同的代码部分)不能改变,可读性更好。并且防止子类重写模板方法,更加专业、安全。
模板方法解决什么问题:
- 提高了代码的复用
- 模板方法已经定义类通用的结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需实现功能即可(在实现类里实现)
接口的定义与特点:
- 接口的格式:
JDK8只能写常量和方法
接口使用interface接口名
public interface 接口名{
//常量
//方法
}
接口就是一种规范,定义方法,然后实现类重写方法内容,简化代码,满足接口设计。
接口定义后被实现类实现,再利用实现类创建实现类对象。
接口的用法:
- 接口是用来被类实现的,实现接口的类称为实现类,与抽象类类似,都是在实现类重写方法,是一种Java面向对象设计。实现类可以理解为所谓的子类。
修饰符 class 实现类 implements 接口1,接口2...{
接口内方法重写(所有接口包含的方法都要实现)
}
- 接口可以被类单实现,也可以被类多实现
- 类可以多实现接口
接口实现的注意事项:
- 一个类实现接口,必须重写全部接口的抽象方法,否则这个类定义为抽象方法
小结:
- 类和类的关系 单继承
- 类和接口关系 一个类可以实现多个接口
- 接口和接口关系 多继承 一个接口可以同时继承多个接口 多继承
接口多继承的作用:
- 规范合并、整合多个接口为同一个接口,便于子类实现
JDK8开始后新增了哪些方法?
- 默认方法:default修饰 实现类对象可以调用
- 静态方法:static修饰 只能接口触发
- 私有方法:private修饰 只能在接口内部被调用
- 以上三种由public默认修饰
JDK新增的三种方法开发中很少使用,通常涉及Java源码,这为以后我们学习Java源码打下了基础。我列出了这些语法,了解即可,真实开发中没有这么杂。
接口注意事项:
- 接口不能创建对象
- 一个类可以实现多个接口,多个接口有相同的静态方法不冲突 接口名.static方法触发
- 一个类继承了父类,同时实现了接口,父类和接口若有同名方法,就近原则
- 一个类实现多个接口,多个接口存在同名,不冲突,这个类重写方法即可
- 一个接口继承多个接口,没问题,若多个接口出现规范冲突,则不能继承
重点:类只能单继承,可以创建对象,可以实现多接口;接口可以多继承接口,不能创建对象。
多态:
- 同类型的对象,执行同一个行为,表现不同特征
多态常见的形式:
父类类型 对象名=new 子类构造器;
接口 接口名=new 实现类构造器;
多态中成员访问特点:
- 方法调用:编译看左边,运行看右边
- 变量调用:编译看左边,运行看左边 (多态侧重行为)
多态的前提:
- 有继承、实现关系,有父类引用指向子类的对象;有方法重写!!!
优势:
- 在多态下,右边的对象可以实现多耦合,便于拓展和维护
- a.run(); 后续业务行为随对象变化而变化没后续改代码无需修改
多态下会产生一个问题:
- 多态下不能使用子类的独有方法 只能使用抽象类方法重写的方法;解决措施,强制转换。
自动类型转换:从子到父 复合多态策略 子类对象赋值给父类类型的变量指向。
强制类型转换:从父到子 实现类对象可以触发独有方法
- 必须强制类型转换:子类 对象变量=(子类)父亲类型的对象变量
- 作用:可以解决多态的劣势,可以实现调用子类的独有方法
- 注意:转换后的类型和真实对象类型不是同一种类型,转换后出现ClassCastException
Java建议强转前使用关键字instanceof判断当前对象的真实类型,再进行强制转换,再调用方法独有方法。
格式:变量名 instanceof 真实类型 返回boolean类型
1、引用数据类型的类型转换,有几种方式?
- 自动类型转换、强制类型转换
2、强制类型能解决什么问题?需要注意的事项?
- 可以转换为自己的真实子类类型,从而调用子类独有的方法
- 有继承关系、实现两个类型就可以进行强制转换,编译无问题。
案例:
设计一个电脑对象、可以安装两个USB设备。鼠标和键盘(安装时有接入、点击、拔出功能)。
使用多态的设计,创建电脑对象、创建两个USB实现对象,分别安装到电脑中触发功能的执行。
内部类:
- 内部类就是定义一个类里面的类,里面的类可以理解为寄生,外面的类可以理解为宿主。
内部类的使用场景:
- 当一个事物的内部还需要一个整体进行描述时,需要使用内部类来设计
- 内部类通常可以访问外类的成员,包括私有成员
- 内部类提供了更好的封装性,内部类本身就可以使用private protected等修饰,封装控制。
内部类的分类:
- 静态内部类 (了解)
- 成员内部类 (了解)
- 局部内部类 (了解)
- 匿名内部类 (重点)
静态内部类:
- static修饰,属于外部类本身
- 特点与普通的类一样,类的成分都有,仅仅是位置在一个类的里面
静态内部类创建对象的格式:
格式:外部类名.内部类名 对象名=new 外部类名.内部类名() 相当于单独创建内部对象
例子:Outer.Inner in=new Outer().Inner();
静态内部类的使用场景、特点、访问总结:
- 内部类就像人类里面还有很多器官类...
- 特点、使用和普通类一样,类的成分他都有,只是位置在一个类的内部
- 可以直接访问外部类的静态成员,不能直接访问其实例成员(属于对象,需要创建)。
- 实际开发中很少,了解即可。
成员内部类:
- 无static修饰,属于外部类的对象,先创建外部对象再创建内部对象
- JDK16之前,成员内部类不能定义静态成员,现在可以了(JDK17)
成员内部类创建对象的格式:
格式:外部类名.内部类名 对象名=new 外部构造器.new 内部构造器;
范例:Outer.Inner in=new Outer().new Inner();
成员内部类的拓展:
1、成员内部类是否可以直接访问外部类的静态成员变量?
可以,外部类的静态成员只有一份被共享
2、成员内部类的实例方法是否可以直接调用外部类的实例成员?
可以的,因为必须先有外部类对象,才有成员内部对象,所以可以直接访问外部类对象的实例成员
注意:在成员内部类中访问所在外部类对象,格式:外部类 this
局部内部类:
局部内部类(鸡肋语法,了解即可)
- 局部内部类放在方法、代码块、构造器执行体里面
- 局部内部类的类文件名为:外部类为$N内部类.class
匿名内部类:
- 定义在代码块、方法中,本质上就是一个没有名字的内部类
- 作用:方便创建子类对象,最终目标为了简化代码
格式:
new 类|抽象名|或者接口名(){
重写方法
};
特点总结:
- 匿名内部类(~)是一个没有名字的内部类
- ~写出来就回产生一个匿名的内部类对象
- ~的对象类型相当于是当前new的那个类型的子类类型
案例:某个学校让老师和同学一起参加游泳比赛
多态的设计 对象回调!!!
总结:内部类可以作为方法的实际参数进行传输
匿名内部类的真实使用场景演示:
给按钮绑定一个点击事件
使用总结:开发中不是我们主动去定义匿名函数,而是别人需要我们写或者我们可以写的时候才用
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
本篇文章暂时告一段落,谢谢大家的阅读,希望对你有帮助,感谢大家!!!
评论区欢迎评论留言,如有问题,欢迎指正!!!