系统温习------黑马程序员Java+AI智能辅助编程全套视频教程
面向对象高级
继承
提高代码的重用性,减少一些重复代码的编写。
Java中提供关键字extends,用这个关键字,可以让一个类和另一个类建立父子关系。
子类能继承父类的非私有成员(成员变量、成员方法)。
子类的对象是由子类、父类共同完成的。
权限修饰符用来限制类中的成员(成员变量、成员方法、构造器)能够被访问的范围.
private:只能本类 缺省:本类、同一个包中的类
protected:本类、同一个包中的类、子孙类中 public:任意位置
java是单继承的:一个类只能继承一个直接父类
java中的类可以多层继承。Object是Java中所有类的祖宗。
子类中访问成员是就近原则,子类有用子类的,子类没有找父类,父类没有就报错。
如果子父类中出现了重名的成员 ,优先使用子类的, 此时一定要在子类中使用父类的:super.父类成员变量/父类成员方法

方法重写:如果子类觉得继承自父类的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样 的方法,去覆盖父类的这个方法。
重写时使用**@Override注解** ,可以指定java编译器,检查 我们方法重写的格式是否正确,代码可读性也会更好。
重写的规范:声明不变,重新实现。
父类的私有方法、静态方法不能被重写,如果重写会报错。
方法重写在开发中的常见应用场景:子类重写Object类的toString()方法,以便返回对象的内容。
直接输出对象,默认会调用Object的toString方法(可以省略不写调用toString的代码),返回对象的地址信息。
输出对象的地址是没有意义的,开发中更希望输出对象时看对象的内容信息 ,所以子类需要重写Object的toString方法。以便以后输出对象时默认就近调用子类重写的toString方法返回对象的内容。
子类全部的构造器,必须先调用父类的构造器,再执行自己的构造器。
默认情况下,子类全部构造器的第一行代码都是super( ) ,它会调用父类的无参数构造器。如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(...),指定去调用父类的有参数构造器。
子类构造器调用父类构造器的应用场景:子类构造器可以通过调用父类构造器,把对象中包含父类这部分的数据先初始化赋值,再回来把对象里包含子类这部分的数据也进行初始化赋值。
this(...)调用兄弟构造器。任意类的构造器中可以通过this(...)去调用该类的其他构造器。
super(...) this(...) 必须写在构造器的第一行,而且两者不能同时出现。
多态
多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。
成员变量:编译看左边,运行也看左边。
方法:编译看左边,运行看右边。
多态的前提:有继承/实现关系;存在父类引用子类对象;存在方法重写。
多态的好处:
在多态形式下,右边对象是解耦合 的,更便于扩展和维护。
定义方法时,使用父类类型的形参,可以接收一切子类对象 ,扩展性更强、更便利。
多态下的问题:多态下不能使用子类的独有功能。
多态下的类型转换问题:
自动类型转换:父类 变量名 = new 子类( );
强制类型转换:子类 变量名 = (子类)父类变量
强制类型转换可以解决多态下调用子类独有功能
存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
运行时 ,如果发现对象的真实类型与强转后的类型不同 ,就会报类型转换异常的错误.
强转前,Java建议:使用instanceof关键字,判断当前对象的真实类型 ,再进行强转.
对象 instanceof 类型 。
加油站支付小模块

①创建卡片类,以便创建金卡或银卡对象,封装车主的数据。
②定义一个卡片父类:Card,定义金卡和银卡的共同属性和方法。共同方法可以考虑预存金额和消费金额这两个方法。
③定义一个金卡类,继承卡片父类。金卡必须重写卡片父类的消费方法(8折优惠),还要再定义一个独有功能打印洗车票。
③定义一个银卡类,继承卡片父类。银卡必须重写卡片父类的消费方法(9折优惠)。
④办一个金卡,创建金卡对象,交给一个独立的业务(支付机)来完成:存款、消费。
④办一个银卡,创建银卡对象,交给一个独立的业务(支付机)来完成:存款、消费。
⑤支付机:用一个静态方法来表示用于刷卡。参数用卡片父类。
lombok技术可以实现自动为类添加getter、setter方法,无参数构造器,toString方法等。直接在类的上面加上@Data注解即可。默认只有无参数构造器,如果要添加有参构造器则再添加@NoAragsConstructor和@AllArgsConstructor注解。

使用lombok技术需要打开IDEA允许使用注解程序的开关。
final
final关键字是最终的意思,可以修饰:类、方法、变量。
修饰类:该类被称为最终类,不能被继承。
修饰方法:该方法被称为最终方法,不能被重写。
修饰变量:该变量有且仅能被赋值一次。
final修饰基本类型的变量,变量存储的数据不能被改变。
final修饰引用类型的变量,变量存储的地址不能被改变 ,但地址所指向对象的内容是可以被改变的。
常量:使用了static final修饰的成员变量就被称为常量。
常量的作用:常用于记录系统的配置信息。
常量的命名规范:使用大写英文单词,多个单词使用下划线连接起来。
使用常量记录系统配置信息的优势、执行原理:代码可读性 更好,可维护性 也更好。程序编译后,常量会被"宏替换" :出现常量的地方全部会被替换成其记住的字面量 ,这样可以保证使用常量和直接用字面量的性能是一样的。
单例类
一个问题通常有n种解法,其中肯定有一种是最优的,这个最优的解法被人总结出来称之为设计模式。关于设计模式主要学①解决什么问题? ②怎么写?
单例设计模式作用:确保某个类只能创建一个对象。
饿汉式单例:拿对象时,对象早就创建好了。
懒汉式单例:拿对象时,才开始创建对象。
饿汉式单例实现步骤:①把类的构造器私有 ;②定义一个类变量记住类的一个对象 ;③定义一个类方法,返回对象。
懒汉式单例实现步骤:①把类的构造器私有 。②定义一个静态变量用于存储对象,此时并不给该变量赋值即为null 。③提供一个静态方法,判断是否为第一次访问,若为第一次才创建对象并给b记住否则直接返回对象即可。

枚举类
枚举类中的第一行,只能写枚举类的对象名称 ,且要用逗号隔开。

这些名称,本质是常量 ,每个常量都记住了枚举类的一个对象。

枚举都是最终类,不可以被继承 ,枚举类都继承java.lang.Enum类的。
枚举类的构造器都是私有的 (写不写都是私有的),因此,枚举类对外不能创建对象。
枚举类适合做信息分类和标志 。参数值受枚举类约束。
常量做信息标志和分类:参数值不受约束。
抽象类
abstract关键字就是抽象的意思,可以用它修饰类、成员方法。
abstract修饰类,这个类就是抽象类。abstract修饰方法,这个方法就是抽象方法。
抽象类中不一定有抽象方法,有抽象方法的类必须是抽象类。
抽象类最主要的特点:抽象类不能创建对象 ,仅作为一种特殊的父类,让子类继承并实现。
抽象方法,必须用abstract修饰,没有方法体。只有方法声明。
一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
类有的成员:成员变量、方法、构造器、抽象类都可以有。
抽象类的应用场景:父类知道每个子类都要做某个行为 ,但每个子类要做的情况不一样 ,父类就定义成抽象方法 ,交给子类去重写实现 ,我们设计这样的抽象类,就是为了更好的支持多态。
模板方法设计模式:提供一个方法作为完成某类功能的模板 ,模板方法封装了每个实现步骤 ,但允许子类提供特定步骤的实现。
模板方法设计模式可以:提高代码的复用 、并简化子类设计。
模板方法设计模式的写法:
①定义一个抽象类;
②在里面定义2个方法:
一个是模板方法:把共同的实现步骤放里面去。
一个是抽象方法:不确定的实现步骤,交给具体的子类来完成。

用final修饰模板方法 的原因:模板方法是给子类直接使用 的,不能被子类重写 。一旦子类重写了模板方法,模板方法就失效了。
接口
Java提供了一个关键字interface定义出接口。JDK8之前,接口中只能定义常量和抽象方法。
接口中定义常量可以省略public static final不写,默认会加上去。
接口中定义抽象方法可以省略public abstract不写,默认会加上去。
接口不能创建对象。接口是用来被类实现 的,实现接口的类称为实现类 ,一个类可以同时实现多个接口。
实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则这个类必须定义成抽象类。
接口的好处:
①弥补了类单继承的不足 ,一个类同时可以实现多个接口,使类的角色更多,功能更强大。
②让程序可以面向接口编程 ,这样程序员就可以灵活方便地切换各种业务实现 (更有利于程序的解耦合)。
班级学生信息管理模块

面向接口编程,接口只规定要做的功能,不用考虑具体实现。具体实现交给实现类。
①定义学生类,创建学生对象,封装学生数据,为数据处理作准备。
②准备学生数据
③提供两套业务实现方案,支持灵活切换(解耦合)。面向接口编程。
--定义一个接口,打印全班学生信息;打印平均分。
--定义第一套实现类,实现接口,实现打印学生信息,实现打印平均分。
--定义第二套实现类,实现接口,实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。
JDK8开始,接口新增了三种形式的方法:
①默认方法(普通实例方法),必须加default修饰 。默认会用public修饰。
如何调用? 使用接口的实现类的对象来调用。
②私有方法(JDK9开始才支持) 私有的实例方法 private修饰
如何调用? 使用接口中的其他实例方法来调用它。
③静态方法 默认会用public修饰
如何调用? 只能使用当前接口名来调用。
新增方法的目的:增强了接口的能力,更便于项目的扩展和维护。

接口与接口可以多继承 ,一个接口可以同时继承多个接口。
一个接口继承多个接口,如果多个接口中存在方法签名冲突 ,则此时不支持多继承,也不支持多实现。

一个类继承了父类,又同时实现了接口。如果父类中和接口中有同名的方法 ,实现类会优先用父类的。

一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。

抽象类和接口
相同点:
①都是抽象形式 ,都可以有抽象方法,都不能创建对象;
②都是派生子类形式 ,抽象类是被子类继承使用 ,接口是被实现类实现;
③一个类继承抽象类,或者实现接口,都必须重写完他们的抽象方法,否则自己要成为抽象类或者报错;
④都能支持多态 ,都能实现解耦合。
不同点:
①抽象类中可以定义类的全部普通成员 ,接口只能定义常量,抽象方法(JDK8新增的三种方式);
②一个类继承抽象类就不能再继承其他类 ,一个类实现接口还可以继承其他类或者实现其他接口。
③抽象类体现模板思想 :更利于做父类 ,实现代码的复用性。 最佳实践
④接口更适合做功能的解耦合 :解耦合性更强更灵活。 最佳实践
智能家居控制系统

角色:设备(吊灯、电视机、洗衣机、落地窗...)
具备的功能:开和关
谁控制他们:智能控制系统(单例对象),控制调用设备的开和关。
①定义设备类:JD,分别创建各个家电类继承设备父类对象代表家里的设备。
②准备这些设备,放到数组中,代表整个家庭的设备。
③为每个设备制定一个开和关的功能è定义一个接口,让JD实现开关功能。
④创建智能控制系统对象(单例模式),控制设备的开和关。
⑤提示用户操作:a.展示全部设备的当前情况;b.让用户选择哪一个操作。