多态

多态的概念

多态主要是指同一种事务表现出来的多种形态 多态的实现需要依赖继承

idea快捷键

command+d 复制当前行代码 option+shift+上下方向键,移动当前行代码

多态的特点

  • 父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调用父类独有的方法
  • 当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接调用子类独有的方法
  • 对于父子类都有的非静态方法来说,编译阶段调用父类的版本,运行阶段调用子类重写的版本(重点 动态绑定)
  • 子类中无法重写父类中的静态方法
  • 对于父类和子类中都有的静态方法,编译和运行都调用父类版本

引用数据类型之间的转换

  • 引用数据类型之间的转换方式有两种:自动类型转换和强制类型转换
  • 自动类型转换主要指小类型向大类型的转换,也就是子类转换为父类,也叫做向上转型
  • 强制类型转换主要指大类型向小类型的转换,也就是父类转换为子类,也叫作向下转型或显示类型转换
  • 引用数据类型的转换必须发生在父子类之间,否则编译报错
  • 若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常
  • 为了避免上述错误的发生,应该在强转之前进行判断,格式如下:

    1. if(引用变量 instanceof 数据类型)
    2. 判断引用变量指向的对象是否为后面的数据类型

多态的意义

  • 多态的实际意义在于屏蔽了不同子类的差异性实现通用的编程带来不同的效果

抽象方法和抽象类

抽象方法的概念

  • 抽象方法主要指不能具体实现的方法并且使用abstract关键字修饰,也就是没有方法体

    public abstract void 方法名;

抽象类的概念

  • 抽象类主要指不能具体实例化的类并且使用abstract关键字修饰,也就是不能创建对象

抽象类和抽象方法的关系

  • 抽象类中可以有成员对象,成员方法和构造方法
  • 抽象类中可以没有抽象方法
  • 拥有抽象方法的必须是抽象类,因此真正意义上的抽象类应该是具有抽象方法并且使用abstract修饰的类

抽象类的意义

  • 抽象类的实际意义不在于创建对象而在于被继承
  • 当一个类继承抽象类后,必须重写抽象方法,否则该类也变成抽象类,也就是抽象类对子类具有强执行和规范性,因此叫做模板设计模式

特别提醒

  • ptivate 和abstract不能共同修饰一个方法
  • final和abstract不能共同修饰一个方法
  • stastic 和abstract不能共同修饰一个方法

接口

接口的基本概念

  • 接口就是一种比抽象类还抽象的类,所有方法都是抽象方法
  • 定义接口的关键字是interface

类和接口之间的关系

屏幕快照 2021-09-19 04.33.52 PM.png

抽象类和接口的区别

  • 定义抽象类关键字是abstract,定义接口的关键字是interface
  • 继承抽象类的关键字是extends,实现接口的关键字是implements
  • 继承抽象类支持单继承,实现接口支持多实现
  • 抽象类中有构造方法,接口中不能有构造方法
  • 抽象类中可以有成员变量,接口中只能有常量
  • 抽象类中有成员方法,接口中只可以有抽象方法
  • 抽象类中增加方法时,子类可以不用重写,而接口中增加方法实现时需要重写(java8以前版本)
  • 从java8开始增加新特性,接口中允许出现非抽象方法和静态方法,但非抽象方法需要使用default关键字修饰
  • 从java9开始增加新特性,允许接口中出现私有方法

特殊类


内部类的基本概念

  • 当一个类的定义出现在另一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)
  • 类中的内容:成员变量、成员方法、构造方法、静态成员、构造块、静态代码块、内部类

内部类的实际作用

  • 当一个类存在的价值仅仅只是为了某一个类单独服务时,那么就可以将这个类定义为所属服务的内部类,这样可以隐藏该类的实现细节并可以方便访问外部类的私有成员而无需提供公有的get和set方法

内部类的分类

  • 普通内部类-直接将一个类的定义放在另外一个类的类体中
  • 局部内部类-直接将一个类的定义放在方法体的内部时
  • 静态内部类-使用statistic关键词修饰的内部类,隶属于类层级
  • 匿名内部类-就是指没有名字的内部类(最常用)

普通(成员)内部类的格式

  1. /*
  2. 访问修饰符 class 外部类名{
  3. 访问修饰符 class 内部类名{
  4. 内部类的类体;
  5. }
  6. }
  7. */

普通内部类的使用方式

  • 普通内部类和普通类一样可以定义成员变量、成员方法及构造方法
  • 普通内部类和普通类一样可以使用final或者abstract关键字修饰
  • 普通内部类还可以使用private和protected关键字修饰
  • 普通内部类需要使用外部类的对象创建对象
  • 如果内部类访问外部类中与本类内部同名的成员变量或方法时,需要使用this关键字

静态内部类的格式

  1. /*
  2. 访问修饰符 class 外部类名{
  3. 访问修饰符 stastic class 内部类名{
  4. 内部类的类体;
  5. }
  6. }
  7. */

局部内部类的使用方式

  • 局部内部类只能在该方法的内部可以使用
  • 局部内部类可以在方法体内部直接创建对象
  • 局部内部类不能使用访问控制符和static关键字修饰符
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。

回调模式的概念

回调模式是指——如果一个方法的参数是接口类型,则在调用该方法时,需要创建并传递一个实现此接口类型的对象,而该方法在运行时会调用到参数对象中所实现的方法(接口中定义的)。

开发经验分享

  • 当接口/类类型的引用作为方法的形参时,实参的传递方法有两种
  • 自定义类实现接口/继承类并重写方法,然后创建该类的对象作为实参传递
  • 使用上述匿名内部类的语法格式得到接口/类类型的引用即可

匿名内部类的语法格式

  1. //接口/父类类型 引用变量名 = new 接口/父类类型(){方法重写}
  2. 优势在于new 完对象后就被销毁
  3. //从java8开始提出新特性,lamda表达式 ,格式为(参数列表) -> { 方法体 }

枚举类的基本概念

  • 在日常生活中事物的描述特征只有固定的几类值,这种列举出来的类型就叫做枚举类型
  • 使用enum关键字来定义枚举类型取代常量
  • 定义的常量类命名结尾增加Enum
  • 枚举类型要求所有枚举值必须放在枚举类型的最前面
  • 所有枚举类都继承自java.lang.Enum常用方法如下

枚举的定义

  • 枚举值就是当前类的类型,也就是指向本类的对象,默认使用public static final关键字共同修饰,因此使用枚举类型.的方式调用
  • 枚举类可以自定义构造方法,但是构造方法的修饰符必须是private,默认也是私有的

Enum类的常用方法

屏幕快照 2021-09-25 04.56.28 PM.png

注解

注解的基本概念

  • 注解(Annotation)也被称为标注,是java5引入的一种引用数据类型
  • 注解本质上就是代码中的特殊标记,通过这些标记可以在编译、类加载和运行时执行指定的处理

注解的语法格式

  1. 访问修饰符 @interface 注解名称{
  2. 注解成员;
  3. //public String value();//声明一个String类型的成员变量,名字为value
  4. }
  5. // 自定义注解自动继承java.lang.annotation.Annotation接口
  6. //通过@注解名称的方式可以修饰包、类、成员方法、成员变量、构造方法、参数、局部变量的声明等
  7. //若一个注解中没有任何的成员,我们就把这种注解称为标记注解/标识注解

注解的使用方式

  • 注解体中只有成员变量,没有成员方法。而注解的成员变量以”无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型
  • 如果注解只有一个参数成员,建议使用参数名为value,而类型只能是八种基本数据类型、String类型、Class类型及Annotation类型

元注解的概念

  • 可以注解在别的注解上的注解
  • 元注解有@Retention、@Documented、@Target、@Inherited、@Repeatable

元注解@Retention

  • @Retention注解运用到一个注解上,用于说明该注解的声明周期,取值如下:
  • RetentionPolicy.SOURCE注解只在源码阶段保留,在编译器编译它时将被丢弃忽视。
  • RetentionPolicy.CLASS注解只保留到编译进行的时候,他并不会加载到JVM中,默认方式
  • RetentionPolicy.RUNTIME注解可以保留到程序运行的时候,他会被加载到JVM中,所以程序在运行的时候可以获取到他们

元注解@Documented

  • 使用avadoc工具可以从程序源代码中抽取类、方法、成员等注释形成一个和源码配套的API帮助文档,而该工具抽取时的默认不包括注解内容
  • @Documented用于将代码中的注解内容可以被javadoc工具提取出来
  • 定义为@Documented的注解必须设置Retention值为RUNTIME

元注解@Target

  • @Target用于指定被修饰的注解能用于哪些元素的修饰,取值如下:

屏幕快照 2021-10-09 11.29.21 PM.png

  • 从java8开始对元注解@Target的参数类型ElementType枚举值增加了两个:
  • 其中ElementType.TYPE_PARAMETER表示该注解能写在类型变量的声明语句中,如:泛型
  • 其中ElementType.TYPE_USE表示该注解能写在使用类型的任何语句中

元注解@Inherited

  • @Inherited并不是说注解本身可以继承,而是说一个超类被该注解被该注解标记过得注解进行注解时,如果子类没有被任何注解应用时,则子类就继承超类的注解

元注解@Repeatable

  • @Repeatable表示自然可重复的含义,从Java8开始增加的新特性

常见的预制注解

屏幕快照 2021-10-10 11.02.20 AM.png
屏幕快照 2021-10-10 11.05.06 AM.png