Java 面向对象3

多态

  1. 基本概念
    • 同一种行为,在不同的对象上,会产生不同的显示结果。
    • 允许不同类的对象对同一消息做出不同的响应
    • 编译时多态
      • 设计时多态 方法重载
    • 运行时多态(通常说的这个)
      • 程序运行时动态决定调用哪个方法
    • 必要条件
      • 满足继承关系
      • 父类引用指向子类对象
  2. 使用
    • 父类引用子类实例
      • 向上转型、隐式转型、自动转型
      • 父类引用指向子类实例,可以调用子类重写父类的方法以及父类派生的方法,无法调用子类独有方法。
      • 小类转型大类
      • 父类 static 方法,不允许子类重写
      • 向上转型后,只能调用到父类原有的静态方法
    • 子类引用指向父类实例
      • 向下转型、强制类型转换
      • 子类引用指向父类对象,此时必须进行强转,可以调用子类独有方法
      • 必须满足转换条件才能进行强转
        • 对象 instanceof 类
        • 判断对象是否是类的实例
          1
          2
          Animal  one = new Cat();
          Cat temp = (Cat)one
  3. 抽象类(abstract)
    • Java 中使用抽象类,限制实例化
      • 通过 abstract 修饰的类,就是抽象类
      • 不允许实例化,可以通过向上转型,指向子类实例
    • 通过abstract 修饰的方法,就是抽象方法
      • public abstract void eat();
      • 子类必须实现这个方法!
    • 应用场景
      • 某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
      • 避免设计随意性,无意义父类实例化
    • 使用规则
      • 1、abstract 定义抽象类
      • 2、抽象类不能直接实例化,只能被继承,可以通过向上转型完成对象实例
      • 3、abstract 定义抽象方法,不需要具体实现
      • 4、包含抽象方法的类是抽象类
      • 5、抽象类中可以没有抽象方法
      • 6、static final private 不能与 abstract 并存
  4. 接口(interface)
    • 基本概念
      • 接口定义了某一批类所需要遵守的规范
      • 接口不关心这些类的内部数据,也不关心这些类里的方法的实现细节,它只规定这些类里必须提供某些方法
    • 语法:
      • [修饰符] interface 接口名 [extends 付接口1, 父接口2…]
        1
        2
        3
        4
        5
        6
        {
        零个到多个常量定义...
        零个到多个抽象方法定义...
        零个到多个默认方法的定义.... (jdk1.8新增)
        零个到多个静态方法的定义... (jdk 1.8新增)
        }
    • 使用注意:
      • 一个类可以实现多个接口,通过逗号分割。 implements
      • 接口的实现要放在继承后面,一个类只能继承唯一父类,但可以实现若干个接口。实现接口的时候要去重写接口待重写的方法。否则通过 abstract 定义抽象类
      • 接口也可以实现继承关系,并且可以继承多个父接口,用逗号分开
      • 如果继承多个接口有多个重名的方法,子类不知道该实现哪个接口的方法,可以重写重名的方法。
        • 如果继承父类的同时,也继承方法。它们都有同名的方法,默认继承父类方法。
    • 代码示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
          package com.zzz.tel;
      // 接口访问修饰符:public 默认
      public interface INet {
      /*接口中抽象方法可以不写abstract关键字
      /*访问修饰符默认public
      * 当类实现接口时,需要去实现接口中的所有抽象方法,否则需要将该类设置为抽象类
      */
      void network();


      //接口中可以包含常量,默认public static final
      int TEMP=20;

      //default:默认方法 可以带方法体 jdk1.8后新增
      //可以在实现类中重写,并可以通过接口的引用调用
      default void connection(){
      System.out.println("我是接口中的默认链接");
      }

      //static:静态方法 可以带方法体 jdk1.8后新增
      //不可以在实现类中重写,可以同接口名调用
      static void stop(){
      System.out.println("我是接口中的静态方法");
      }
      }
  5. 内部类
    • 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
    • 与之对应,包含内部类的类被称为外部类
    • 内部类隐藏在外部类之内,更好的实现了信息的隐藏。不允许其它类随意的访问。
    • 内部类分类
      • 1、成员内部类
        • 内部类中最常见的就是成员内部类,也称普通内部类
        • 1、内部类在外部使用时,无法直接实例化,需要借由外部类的信息才能完成实例化
        • 2、内部类的访问修饰符,可以任意,但是访问范围会受到影响
        • 3、内部类可以直接访问外部类的成员,如果出现同名属性,优先访问内部类中定义的
        • 4、可以使用 外部类.this.成员 的方式,访问外部类中同名的信息
        • 5、外部类访问内部类信息,需要通过内部类实例,无法直接访问
        • 6、内部类编译后 .class 文件命名:外部类$内部类.class
        • 内部类的获取方式
          • 1、new 外部类.new 内部类
          • 2、外部类对象.new 内部类
          • 3、外部类对象.获取方法
      • 2、静态内部类
        • 【成员共享】静态内部类对象可以不依赖于外部类对象,直接创建
        • 1、静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例
        • 2、静态内部类对象实例时,可以不依赖于外部类对象
        • 3、可以通过 外部类.内部类.静态成员 的方式,访问内部类中的静态成员
        • 4、当内部类属性与外部类属性同名时,默认直接调用内部类中的成员;如果需要访问外部类中的静态属性,则可以通过 外部类.属性 的方式;如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性 的方式;
      • 3、方法内部类
        • 定义在外部类方法中的内部类,也称局部类。
        • 1、定义在方法内,作用范围也在方法内
        • 2、和方法内部成员使用规则一样,class 前面不可以添加 public、private、protected、static
        • 3、类中不能包含静态成员
        • 4、类中可以包含 final、abstract 修饰的成员
      • 4、匿名内部类
        • 将类的定义与类的创建,放到一起完成
        • 1、匿名内部类没有类型名称、实例对象名称
        • 2、编译后的文件命名:外部类$数字.class
        • 3、无法使用 private、public、protected、abstract、static 修饰
        • 4、无法编写构造方法,可以添加代码块
        • 5、不能出现静态成员
        • 6、匿名内部类可以实现接口也可以继承父类,但是不可兼得
        • 适用场景
          • 1、只有到类的一个实例
          • 2、类在定义后马上用到
          • 3、给类命名并不会导致代码更容易被理解