一. 单例模式
-
定义
- 单例也叫单态模式, 是设计模式中最简单的一种. 当一个类被创建之后, 只能产生一个实例供外部访问, 并且提供一个全局访问的方法
- 单例的最终目的就是保证一个类在内存中只能有一个实例(对象)
- Java中频繁创建和销毁类对象都会占用一部分系统资源,使用单例模式可以提高性能
- 单例模式创建的对象不会被回收, 过多的单例容易造成内存溢出
-
创建过程
- 私有化构造方法 (使用private 修饰)
- 在其内部产生该类的实例化对象,并将其封装成private static 类型
- 定义一个静态的方法返回该类的实例
-
饿汉式 和 懒汉式
-
饿汉式
public class Singleton { //创建唯一的永远存在的静态变量 private static Singleton singleton = new Singleton(); //私有化构造方法 private Singleton(){ } //提供外部访问接口 public static Singleton getInstance(){ return singleton; } }
-
懒汉式
public class Singleton { //创建唯一的永远存在的静态变量 private static Singleton singleton ; //私有化构造方法 private Singleton(){ } //提供外部访问接口 public static Singleton getInstance(){ //第一次访问的时候创建对象 if(singleton==null){ singleton = new Singleton(); } return singleton; } }
-
-
注意事项
- 单例模式总共有七中基本写法
- 我们现阶段写的都是线程不安全
-
应用场景
- 适用于全局只需要一个的情况下
- 比如, windows系统的任务管理器, java中的日历类
-
测试题
- 全公司只有一个保洁, 所有的需要保洁的部门只需要通知保洁小妹就可以了
- 使用单例模式, 提供打扫卫生的方法
二. 继承 (extends)
-
定义
- 从生活中的理解, 我们可以明白, 继承就是从前辈手里获取一些好处
- 编程语言中的继承是指让类和类之间产生关系 , 子父类关系
-
优缺点
- 优点
- 就是为了获取到父类中的方法和属性
- 提高了代码的复用性和维护性
- 让类和类之间产生关系,是多态的前提
- 缺点
- 类的耦合性增强了 , 我们开发的原则是高内聚,低耦合
- 耦合: 类与类的关系
- 内聚: 独立完成工作的能力
- 优点
-
开发步骤
- 使用extends关键字让子类和父类产生联系
//父类 public class Father { String name = "小红"; public void method(){ System.out.println(name); } } //子类 public class Son extends Father{ } //调用 public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.method(); } }
-
测试题
- 判断结果
public class Father { String name = "小红"; public void method(){ System.out.println(name); System.out.println(age); } } public class Son extends Father{ int age = 18; public void show(){ System.out.println("展示效果"); System.out.println(name); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.method(); son.show(); Father father = new Father(); father.show(); } }
三. 继承案例演示
- 公司员工
- 关系
- 程序员
- 人事
- 共有方法 : 打卡 sign();
- 特有方法
- 程序员 : 敲代码
- 人事 : 招聘
- 关系
- 动物 extends
- 关系
- 猫
- 狗
- 共有方法 : 吃饭 eat()
- 特有方法
- 猫 : 卖萌
- 狗 : 看家
- 关系
- 汽车
- 关系
- 轿车
- 拖拉机
- 共有方法 : 开动 run()
- 特有方法
- 拖拉机 : 拉货
- 轿车 : 载人
- 关系
- 老师授课
- 关系
- 音乐老师
- 数学老师
- 共有方法 : 授课 teach()
- 特有方法
- 音乐老师 : 心灵安慰(warmHeart)
- 数学老师 : 终极题库奥义
- 关系
四. 继承中的注意事项
-
this 和 super 关键字
- this 代表本类对象
- super 代表父类对象
- this.成员 调用本对象中的成员,也可以调用父类中的成员(当子类中没有的时候)
- super.成员 调用父类的成员
- this(…) 调用本对象的构造方法
- super(…) 调用父对象的构造方法
public class Father { String name = "小红"; public void method(){ System.out.println(name); } } public class Son extends Father{ String name = "小张"; public void show(){ System.out.println(this.name); //调用父类的成员变量 System.out.println(super.name); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.method(); } }
-
继承中构造方法的关系
- 子类中的所有构造方法都会默认访问父类中的无参构造方法
- 因为子类继承父类中的数据 ,可能还会使用父类中的数据, 所有子类在初始化的时候, 需要将父类先初始化
- 每一个子类构造方法的第一条语句默认都是:super(), Object类最顶层的父类
public class Son extends Father{ String name = "小张"; public Son(String name) { //会默认调用父类无参的构造方法 super(); this.name = name; } }
- 当父类中没有空参构造的时候, 子类会报错, 这时我们可以采用调用父类的有参构造,并赋上默认值
-
继承中成员的关系
-
子类无法使用父类私有的成员
public class Father { private String name = "小明"; private void show(){ System.out.println(name); } } public class Son extends Father{ public void method() { //报错,找不到 System.out.println(name); }
-
}
public class TestDemo {
public static void main(String[] args) {
Son son = new Son();
//报错, 找不到show方法
son.show();
son.method();
}
}
```
-
子父类中出现了一样的成员变量, 还是采用就近原则
public class Father { String name = "小红"; public void show(){ System.out.println(name); } } public class Son extends Father{ String name = "小明"; public void method() { String name = "小刚"; System.out.println(name); System.out.println(this.name); System.out.println(super.name); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.show(); son.method(); } }
-
测试题
- 判断结果
public class Father { String name = "小明"; public void show(){ System.out.println(name); } } public class Son extends Father{ String name = "小红"; public void method() { System.out.println(name); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.show(); son.method(); } }
-
继承中的初始化顺序
- 加载父类 加载子类 父类类初始化 子类类初始化 创建父类对象 创建子类对象 初始化父类 初始化子类
- 静态优先 父类优先 成员变量----构造代码块 ----- 构造方法
-
其他注意事项
- 使用时, 尽量使用最底层的子类, 最底层的子类的功能是最全的
- 查看这个体系中共性的功能, 就去查看顶层的父类
- 不要为了继承而继承
五. 方法重写(overriding)
-
定义
- 子父类中出现了一模一样的方法
- 重写是一种现象, 也是一个动作
- 当子类需要父类的功能, 而子类有自己特有内容时, 可以重写父类的方法, 这样 , 既延续了父类的功能 , 又定义了子类特有的内容
-
演示
- 聊天软件的升级
public class Father { public void talking(){ System.out.println("纯文字聊天"); } public void shipin(){ } } public class Son extends Father{ public void talking() { System.out.println("文字加图片的聊天"); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.talking(); } }
-
重写的意义
- 子类重写父类的方法,主要是要使用父类方法的主体和名称, 当子类中重写了父类的方法, 如果不是用父类的名称那么, 使用这的辨识度极低
-
测试题
- 老师都有授课和辅导作业的能力, 但每个老师授课的风格内容不一样, 编程模拟
六. 重写的注意事项
-
私有方法
- 父类中私有方法不能被重写
- 因为父类私有方法子类根本无法继承
-
权限
- 子类重写父类方法时, 访问权限不能更低
- 最好保持一致
-
静态方法
- 父类的静态方法, 子类也必须通过静态方法重写
- 重写其实是全遮挡, 调用者无法在通过任何方式去调用和子类关联的父类对象中的方法
- 但是静态无法做到全遮挡, 我们依然可以直接使用父类中的方法
public class Father { static String name = "小明"; public static void method(){ System.out.println("父类方法"+name); } } public class Son extends Father{ public static void method() { System.out.println("子类方法"+name); } } public class TestDemo { public static void main(String[] args) { Son son = new Son(); son.name = "小明"; son.method(); Father.method(); } }
七. instanceof关键字
-
定义
- 用来判断一个对象是否属于一个类或者此类的父类
-
用法
- 对象 instanceof 类名
- 该表达式是一个比较运算符,返回的结果是boolean类型 true | false
-
演示
public class TestDemo { public static void main(String[] args) { Son son = new Son(); //判断son的是否属于Son类型 boolean b = son instanceof Son; System.out.println(b); //判断son的类型是否属于Son类型的父类 b = son instanceof Father; System.out.println(b); } }
总结:
-
单例模式
模式 : 解决问题的最好办法
单例 : 一个类只能创建一个对象
优点 : 节省静态方法区的内容, 调用成员时速度快
实施步骤 :
- 私有化构造方法
- 提供永久存放对象的变量(一个静态变量)
- 提供获取对象的方法(静态方法)
-
继承
继承就是exetends关键字
写在子类类名的后面 子类类名 extends 父类类名
子类继承父类, 子类可以直接使用父类中已经存在的成员
优点 : 提高代码的复用性 和 维护性
缺点 : 耦合性增强, 开发讲究高内聚,低耦合
作用 : 一般来说, 如果多个类中出现相同的成员, 我们会提取出来放在父类中
- 继承的注意事项
super : 父类对象
- 指明使用父类对象中的成员, 如果子父类中出现了相同名称的成员, 可以使用super来指明使用父类对象的
- super() : 在子类中指明父类对象初始化的构造方法是哪个 ,必须写在子类构造方法的第一个执行语句
子父类对象:
创建子类对象 一定会先创建父类对象
加载父类 ,加载子类, 初始化父类, 初始化子类, 创建父类对象 ,创建子类对象, 初始化父类对象,初始化子 类对象
子类无法继承父类的私有化成员
- 重写
在子类中写一个和父类中格式一样的方法(主要看方法名和参数列表), 这种现象叫重写
就是用子类中的方法覆盖父类中的方法
-
重写的注意事项
父类中的私有方法不能重写
重写方法时权限不能更低 (建议保持一直)
静态方法必须使用静态方法重写
-
instanceof关键字
判断对象是否属于这个类型
作业
- 第一题
- 飞机都有飞行的功能, 运输机可以运送物资, 战斗机可以发动攻击, 使用继承编程模拟
- 第二题
- 快递员都有送快递的功能, 顺丰快递员还有扔垃圾的功能, 申通快递员有偷吃客户水果的功能, 编程模拟
- 第三题
- 动物类都有吃饭, 睡觉的功能, 但是小猫是吃小鱼干, 小狗是吃骨头, 编程模拟
- 第四题
- 一代的笔记本电脑是可以玩LOL, 二代笔记本性能强劲,不但能玩LOL,还能玩刺客信条, 编程模拟
- 扩展题
- 思考, 猫, 小狗都有自己的特性, 生活中, 这两个种类我们也都统称为动物, 为什么