Day09

一. 单例模式

单例模式.png
  1. 定义

    • 单例也叫单态模式, 是设计模式中最简单的一种. 当一个类被创建之后, 只能产生一个实例供外部访问, 并且提供一个全局访问的方法
    • 单例的最终目的就是保证一个类在内存中只能有一个实例(对象)
    • Java中频繁创建和销毁类对象都会占用一部分系统资源,使用单例模式可以提高性能
    • 单例模式创建的对象不会被回收, 过多的单例容易造成内存溢出
  2. 创建过程

    • 私有化构造方法 (使用private 修饰)
    • 在其内部产生该类的实例化对象,并将其封装成private static 类型
    • 定义一个静态的方法返回该类的实例
  3. 饿汉式 和 懒汉式

    • 饿汉式

      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;
         }
      }
      
  4. 注意事项

    • 单例模式总共有七中基本写法
    • 我们现阶段写的都是线程不安全
  5. 应用场景

    • 适用于全局只需要一个的情况下
    • 比如, windows系统的任务管理器, java中的日历类
  6. 测试题

    • 全公司只有一个保洁, 所有的需要保洁的部门只需要通知保洁小妹就可以了
    • 使用单例模式, 提供打扫卫生的方法

二. 继承

  1. 定义

    • 从生活中的理解, 我们可以明白, 继承就是从前辈手里获取一些好处
    • 编程语言中的继承是指让类和类之间产生关系 , 子父类关系
  2. 优缺点

    • 优点
      • 就是为了获取到父类中的方法和属性
      • 提高了代码的复用性和维护性
      • 让类和类之间产生关系,是多态的前提
    • 缺点
      • 类的耦合性增强了 , 我们开发的原则是高内聚,低耦合
      • 耦合: 类与类的关系
      • 内聚: 独立完成工作的能力
  3. 开发步骤

    • 使用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();
     }
    }
    
  4. 测试题

    • 判断结果
    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();
     }
    }
    

三. 继承案例演示

  1. 公司员工
    • 关系
      • 程序员
      • 人事
    • 共有方法 : 打卡 sign();
    • 特有方法
      • 程序员 : 敲代码
      • 人事 : 招聘
  2. 动物 extends
    • 关系
    • 共有方法 : 吃饭 eat()
    • 特有方法
      • 猫 : 卖萌
      • 狗 : 看家
  3. 汽车
    • 关系
      • 轿车
      • 拖拉机
    • 共有方法 : 开动 run()
    • 特有方法
      • 拖拉机 : 拉货
      • 轿车 : 载人
  4. 老师授课
    • 关系
      • 音乐老师
      • 数学老师
    • 共有方法 : 授课 teach()
    • 特有方法
      • 音乐老师 : 心灵安慰(warmHeart)
      • 数学老师 : 终极题库奥义

四. 继承中的注意事项

  1. this 和 super 关键字

    • 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();
 }
}
  1. 继承中构造方法的关系

    • 子类中的所有构造方法都会默认访问父类中的无参构造方法
    • 因为子类继承父类中的数据 ,可能还会使用父类中的数据, 所有子类在初始化的时候, 需要将父类先初始化
    • 每一个子类构造方法的第一条语句默认都是:super(), Object类最顶层的父类
    public class Son extends Father{
     String name = "小张";
     
     public Son(String name) {
         //会默认调用父类无参的构造方法
         super();
         this.name = name;
     }
     
    }
    
    • 当父类中没有空参构造的时候, 子类会报错, 这时我们可以采用调用父类的有参构造,并赋上默认值
  2. 继承中成员的关系

    • 子类无法使用父类私有的成员

      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();
         }
      }
      
  3. 测试题

    • 判断结果
    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();
     }
    }
    
    
  4. 继承中的初始化顺序

    • 加载父类 加载子类 父类类初始化 子类类初始化 创建父类对象 创建子类对象 初始化父类 初始化子类
父类与子类.png
  • 静态优先 父类优先 成员变量----构造代码块 ----- 构造方法
  1. 其他注意事项

    • 使用时, 尽量使用最底层的子类, 最底层的子类的功能是最全的
    • 查看这个体系中共性的功能, 就去查看顶层的父类
    • 不要为了继承而继承

五. 方法重写(overriding)

  1. 定义

    • 子父类中出现了一模一样的方法
    • 重写是一种现象, 也是一个动作
    • 当子类需要父类的功能, 而功能主体子类有自己特有内容时, 可以重写父类的方法, 这样 , 既延续了父类的功能 , 又定义了子类特有的内容
  2. 演示

    • 聊天软件的升级
    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();
         
     }
    }
    
    
  3. 重写的意义

    • 子类重写父类的方法,主要是要使用父类方法的主体和名称, 当子类中重写了父类的方法, 如果不是用父类的名称那么, 使用这的辨识度极低
  4. 测试题

    • 老师都有授课和辅导作业的能力, 但每个老师授课的风格内容不一样, 编程模拟

六. 重写的注意事项

  1. 私有方法

    • 父类中私有方法不能被重写
    • 因为父类私有方法子类根本无法继承
  2. 权限

    • 子类重写父类方法时, 访问权限不能更低
    • 最好保持一致
  3. 静态方法

    • 父类的静态方法, 子类也必须通过静态方法重写
    • 重写其实是全遮挡, 调用者无法在通过任何方式去调用和子类关联的父类对象中的方法
    • 但是静态无法做到全遮挡, 我们依然可以直接使用父类中的方法
    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关键字

  1. 定义

    • 用来判断一个对象是否属于一个类或者此类的父类
  2. 用法

    • 对象 instanceof 类名
    • 该表达式是一个比较运算符,返回的结果是boolean类型 true | false
  3. 演示

    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);
         
     }
    }
    
    

总结:

  1. 单例模式

    • 解决一个类在内存中如何只保持一个对象的问题

    • 类为什么要在内存中只有一个对象?

      • 节省创建对象的时间和存储对象的空间,而且不会占用静态方法区的空间
    • 私有化构造方法

    • 定义一个私有化的静态变量用来存放我们自己创建的对象

    • 提供一个静态的方法,供用户获取对象

  2. 继承

    • 子类类名 extends 父类类名
    • 子类可以使用父类的非私有成员
    • 提高了代码的复用性 和 维护性
    • 类和类之间的关系加强了, 不符合编程的理念
  3. 注意事项

    • 父类中的私有化成员不能继承
    • super关键字
    • 构造方法, 子类会默认访问父类的空参构造,我们没写,编译器会自动加上
      • 如果父类中没有空参构造, 子类会报错
      • 需要我们手动调用父类的空参构造,或者去父类中添加一个空参构造
      • super() 必须是子类构造方法的第一条执行语句
  4. 方法的重写

    • 子类和父类中出现了一模一样的方法, 这种现象叫做重写
    • 方法名和参数列表必须一样
    • 子类重写父类的方法, 意味着, 子类的方法对父类的方法形成了全遮挡
  5. 注意事项

    • 子类的权限不能比父类低
    • 父类的中的方法如果是静态的, 子类重写的时候也必须是静态的
    • 父类的私有化方法不能重写, 因为压根看不见
  6. instanceof关键字

    • 用来比较对象是不是属于这个类或者这个类的父类

作业

  1. 第一题
    • 飞机都有飞行的功能, 运输机可以运送物资, 战斗机可以发动攻击, 使用继承编程模拟
  2. 第二题
    • 快递员都有送快递的功能, 顺丰快递员还有扔垃圾的功能, 申通快递员有偷吃客户水果的功能, 编程模拟
  3. 第三题
    • 动物类都有吃饭, 睡觉的功能, 但是小猫是吃小鱼干, 小狗是吃骨头, 编程模拟
  4. 第四题
    • 一代的笔记本电脑是可以玩LOL, 二代笔记本性能强劲,不但能玩LOL,还能玩刺客信条, 编程模拟
  5. 扩展题
    • 思考, 猫, 小狗都有自己的特性, 生活中, 这两个种类我们也都统称为动物, 为什么

你可能感兴趣的:(Day09)