zoukankan      html  css  js  c++  java
  • 03.继承、多态、接口、权限、内部类、static

    一、继承

    • 概念
      • 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
      • 好处
        • 提高代码的复用性
        • 类与类之间产生了关系,是多态的前提
    • 继承特点
      • Java 只支持单继承,不支持多继承。
      • Java 支持多层继承 (继承体系)。
      • 子类和父类是一种相对的概念。
      • 顶层父类是 Object 类。所有的类默认继承 Object,作为父类。
    • 格式
      • public    class    子类名称    extends    父类名称  {...}
    • 继承后的特点
      • 成员变量,分两种情况
        • 成员变量不重名
          • 没有影响。
        • 成员变量重名,创建子类对象时,访问有两种方式
          • 直接通过子类对象访问成员变量
            • 等号左边是谁,就优先用谁,没有则向上找。
          • 间接通过成员方法访问成员变量
            • 该方法属于谁,就优先用谁,没有则向上找。
        • 成员变量重名,子类中需要访问父类中非私有成员变量时
          • 使用 super 关键字,类似于之前学过的 this 。
            • 格式
              • super.父类成员变量名
      • 成员方法
        • 成员方法不重名
          • 没有影响,子类有就执行,子类没有就去父类找。
        • 成员方法重名,涉及到方法的重写
          • 创建的对象是谁,就优先用谁,如果没有则向上找。
        • 重写(Override)
          • 概念:在继承关系当中,方法的名称一样,参数列表也一样。
          • 特点:创建的是子类对象,则优先用子类方法。
          • 重写注意事项
            • 必须保证父子类之间方法的名称相同,参数列表也相同,
              • @Override:写在方法上面,用来检测是不是有效的正确覆盖重写,这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。
            • 子类方法的返回值必须【小于等于】父类方法的返回值范围。
            • 子类方法的权限必须【大于等于】父类方法的权限修饰符。
              • public > protected > (default) > private
                • ( default )不是关键字 default,而是什么都不写,留空。
          • 重写(Override)与重载(Overload)
            • 重写:方法的名称一样,参数列表【也一样】。覆盖、覆写。
            • 重载:方法的名称一样,参数列表【不一样】
      • 构造方法
        • 继承关系中,父子类构造方法的访问特点
          • 子类构造方法当中有一个默认隐含的 “ super() ” 调用,所以一定是先调用的父类构造,后执行的子类构造。
          • 子类构造可以通过 super 关键字来调用父类重载构造。
          • super 的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次 super 构造。
          • 只有子类的构造方法,才能调用父类构造方法。
        • 总结
          • 子类必须调用父类构造方法,不写则赠送 super();写了则用写的指定的 super 调用,super 只能有一个,还必须是第一个。
      • super 关键字三种用法
        • 在子类的成员方法中,访问父类的成员变量。
        • 在子类的成员方法中,访问父类的成员方法。
        • 在子类的构造方法中,访问父类的构造方法。
      • super 关键字用来访问父类内容,而 this 关键字用来访问本类内容。用法也有三种
        • 在本类的成员方法中,访问本类的成员变量。
        • 在本类的成员方法中,访问本类的另一个成员方法。
        • 在本类的构造方法中,访问本类的另一个构造方法。
          • 第三种用法当中要注意
            • this (...)调用也必须是构造方法的第一个语句,唯一一个。
            • super 和 this 两种构造调用,不能同时使用。

    二、抽象类

    • 由来
      • 父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java 语法规定,包含抽象方法的类就是抽象类
      • 抽象方法
        • 普通方法加上 abstract 关键字修饰,然后去掉大括号,直接分号结束。
      • 抽象类
        • 抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。
      • 如何使用抽象类和抽象方法
        • 不能直接创建 new 抽象类对象。
        • 必须用一个子类来继承抽象父类。
        •  子类必须覆盖重写抽象父类当中所有的抽象方法。
          • 子类去掉抽象方法的 abstract 关键字,然后补上方法体大括号。
        • 创建子类对象进行使用。
      • 注意事项
        • 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
          • 理解:子类的构造方法中,有默认的 super(),需要访问父类构造方法
        • 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
          • 未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

    三、接口

    • 概述
      • 接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
    • 接口定义
      • 使用 interface 关键字
        • 格式
          • public interface 接口名称 { 接口内容 }
    • 含有抽象方法
      • 使用 public abstract 关键字修饰,可以省略,没有方法体。
        • 格式
          • public     abstract     返回值类型    方法名称 (  参数列表    );
    • 含有默认方法和静态方法
      • 默认方法
        • 使用 default 修饰,不可省略,供子类调用或者子类重写。
        • 格式
          • public    default     返回值类型     方法名称  ( 参数列表 )  {  方法体  }
      • 静态方法
          • 使用 static 修饰,供接口直接调用。
          • 格式
            • public    static    返回值类型    方法名称 (  参数列表  )  {  方法体  }
    • 含有普通私有方法和私有静态方法
      • 普通私有方法
        • 解决多个默认方法之间重复代码问题。
          • 格式
            • private    返回值类型    方法名称 ( 参数列表 ) { 方法体 }
      • 私有静态方法
        • 解决多个静态方法之间重复代码问题。
          • 格式
            • private    static    返回值类型    方法名称 ( 参数列表 )  {  方法体  }
    • 接口当中也可以定义 “成员变量” ,但是必须使用 public    static    final 三个关键字进行修饰。
      • 从效果上看,这其实就是接口的【常量】
        • 格式
          • public    static    final    数据类型    常量名称    =    数据值  ;、
        • 注意事项
          • 接口当中的常量,可以省略 public static final,注意:不写也照样是这样。
          • 接口当中的常量,必须进行赋值;不能不赋值。
          • 接口中常量的名称,使用完全大写的字母,用下划线进行分隔。(推荐命名规则)
    • 接口的使用 (实现)
      • 接口不能直接使用,必须有一个 “实现类” 来 “实现” 该接口。
        • public    class    实现类名称    implements    接口名称 {  //...}
      • 接口的实现类必须覆盖重写(实现)接口中所有的抽象方法。
        • 实现:去掉 abstract 关键字,加上方法体大括号。
      • 创建实现类的对象,进行使用。
      • 注意事项
        • 如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。
    • 接口实现分类
      • 接口的默认方法
        • 可以通过接口实现类对象,直接调用。
        • 可以被接口实现类进行覆盖重写。
      • 接口的静态方法
        • 通过接口名称,直接调用其中的静态方法。
        • 不能通过接口实现类的对象来调用接口当中的静态方法。
      • 接口的抽象方法
        • 实现:去掉 abstract 关键字,加上方法体大括号。
        • 如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。
      • 接口的普通私有方法和静态私有方法
        • 普通私有方法
          • 只有默认方法可以调用
        • 静态私有方法
          • 默认方法和静态方法可以调用。
    • 注意事项
      • 接口是没有静态代码块或者构造方法的。
      • 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。
      • 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
      • 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
      • 如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
      • 一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。

    四、多态

    • 定义
      • 是指同一行为,具有多个不同表现形式。
        • 其实就是一句话:父类引用指向子类对象
    • 格式
      • 父类名称    对象名    =    new    子类名称 ();
      • 接口名称    对象名    =    new    实现类名称 ();
    • 访问成员变量
      • 直接通过对象名称访问成员变量
        • 看等号左边是谁,优先用谁,没有则向上找。
      • 间接通过成员方法访问成员变量
        • 看该方法属于谁,优先用谁,没有则向上找。
    • 访问成员方法
      • 看 new 的是谁,就优先用谁,没有则向上找。
        • 编译看左边,运行看右边
    • 口诀
      • 成员变量:编译看左边,运行还看左边。
      • 成员方法:编译看左边,运行看右边。
    • 多态的转型
      • 分为向上转型和向下转型
        • 向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的
          • 向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端
            • 对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。
            • 解决方案:向下转型
        • 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的
          • 操作方法:强制类型转换
    • 如何才能知道一个父类引用的对象,本来是什么子类?
      • 格式
        • 对象    instanceof    类名称
        • 这将会得到一个 boolean 值结果,也就是判断前面的对象能不能当做后面类型的实例。

    五、final 关键字

    • 常见四种用法
      • 修饰一个类
        • 修饰的这个类不能有任何的子类
          • 一个类如果是 final 的,那么其中所有的成员方法都无法进行覆盖重写。
      • 修饰一个方法
        • 使用 final 来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
      • 修饰一个局部变量
        • 使用 final 用来修饰局部变量,那么这个变量就不能进行更改。
        • 一次赋值,终生不变
      • 修饰一个成员变量
        • 使用 final 关键字修饰,那么这个变量也照样是不可变。
          • 由于成员变量具有默认值,所以用了 final 之后必须手动赋值,不会再给默认值了。
          • 对于 final 的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
          • 必须保证类当中所有重载的构造方法,都最终会对 final 的成员变量进行赋值。

    六、权限修饰符

    • 四种权限修饰符

       

    七、内部类

    • 定义
      • 将一个类 A 定义在另一个类 B 里面,里面的那个类 A 就称为内部类,B 则称为外部类。
      • 分类:两大类三种。
        • 成员内部类
        • 局部内部类(匿名内部类)
      • 权限修饰符
        • 外部类:public / (default)
        • 成员内部类:public / protected / (default) / private
        • 局部内部类:什么都不能写
    • 成员内部类
      • 格式
        • 修饰符  class  外部类名称 {
          • 修饰符   class   内部类名称 {
            • // ...
          • }
          • // ...
        • }
      • 注意:内用外,随意访问;外用内,需要内部类对象。
      • 如何使用成员内部类?有两种方式。
        • 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
        • 直接方式,公式:
          • 【 外部类名称.内部类名称  对象名  =  new  外部类名称 ().new  内部类名称 (); 】
    • 局部内部类
      • 如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
        • 格式
          • 修饰符 class 外部类名称 {
            • 修饰符 返回值类型 外部类方法名称(参数列表) {
              • class 局部内部类名称 {
                •  // ...
              • }
            • }
          • }
      • 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效 final 的】。
        • 原因
          • new 出来的对象在堆内存当中。
          • 局部变量是跟着方法走的,在栈内存当中。
          • 方法运行结束之后,立刻出栈,局部变量就会立刻消失。
          • 但是 new 出来的对象会在堆当中持续存在,直到垃圾回收消失。
        • 备注
          • 从 Java 8+ 开始,只要局部变量事实不变,那么 final 关键字可以省略。
    • 匿名内部类
      • 如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】
      • 格式
        • 接口名称 对象名 = new 接口名称() {
          • // 覆盖重写所有抽象方法
        • };
      • 对格式 “ new 接口名称() {...}” 进行解析
        • new 代表创建对象的动作
        • 接口名称就是匿名内部类需要实现哪个接口
        • {...} 这才是匿名内部类的内容
      • 匿名内部类注意事项
        •  匿名内部类,在【创建对象】的时候,只能使用唯一一次。
          • 如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
        • 匿名对象,在【调用方法】的时候,只能调用唯一一次。
          • 如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
        • 匿名内部类是省略了【实现类/子类名称】,有对象名称;但是匿名对象是省略了【对象名称】
          • 强调:匿名内部类和匿名对象不是一回事!!!

     八、static 关键字

    • 概述
      • static 可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。
    • 当 static 修饰成员变量
      • 该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
    • 当 static 修饰成员方法
      • 该方法称为静态方法。静态方法不属于对象,而是属于类的。直接就能通过类名称来使用它。
    • 无论是成员变量,还是成员方法。如果有了static,都推荐使用类名称进行调用。
      • 静态变量:类名称.静态变量
      • 静态方法:类名称.静态方法()
    • 注意事项
      • 静态不能直接访问非静态。
        • 因为在内存当中是【先】有的静态内容,【后】有的非静态内容。
        • “先人不知道后人,但是后人知道先人。
      • 静态方法当中不能用this。
        • 因为 this 代表当前对象,通过谁调用的方法,谁就是当前对象。
    • 静态代码块
      • 定义在成员位置,使用 static 修饰的代码块 { }
      • 格式
        • public class 类名称 {
          • static {
            • // 静态代码块的内容
          • }
        • }
      • 特点
        • 当第一次用到本类时,静态代码块执行唯一的一次
        • 静态内容总是优先于非静态,所以静态代码块比构造方法先执行。
      • 静态代码块的典型用途
        • 用来一次性地对静态成员变量进行赋值。

    九、继承、多态、接口、权限、内部类、static 完结

  • 相关阅读:
    CodeForces 55D Beautiful numbers(数位dp+数学)
    hdu 2089 不要62(数位dp入门)
    Git版本控制
    Git初始化-添加提交以及查看状态
    linux-高并发与负载均衡-lvs-3种模型推导
    Scrapy中选择器的用法
    Scrapy命令行详解
    Scrapy框架基本用法讲解
    MaxCompute教程
    Scrapy安装报错
  • 原文地址:https://www.cnblogs.com/_Moliao/p/12448798.html
Copyright © 2011-2022 走看看