【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。

1. 抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,

  • 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
  • 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法、初始化块和构造方法和普通类一样。

并且抽象类和普通类相比还多出了抽象方法。

格式:

[修饰符] abstract class 类名{
   
    //零到多个成员变量
    //零到多个构造器
    //零到多个普通方法
    //零到多个抽象方法
    //零到多个初始化块
}

1.1 抽象方法:

抽象方法只包含一个方法名,而没有方法体,使用abstract修饰。
格式:

[修饰符] abstract 返回值类型 方法名(形参列表);

修饰符 (public protected private) 三选一

1.2 抽象类总结:

  1. 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。
  2. 抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。
  3. 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。
  4. 抽象类的构造器不能用于创建实例,主要是用于被其子类调用。
  5. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
  6. abstract static不能同时修饰一个方法
  7. 抽象类可以有主函数,可以执行。

2. 接口 interface

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。

  • 一个类通过实现接口的方式,从而来实现接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

2.1 接口定义

[public] interface InterfaceOne [extends fatherInterface1,fatherInterface2...]{
   
    [public] [static] [final] type CONSTANT_NAME=Value;//定义常量
    //[public] [static] [final]可以不写,一般也不用写。 编译时自动为接口里定义的成员变量增加public static final修饰符

    [public] [abstract] returnType methodName(参数列表);//声明方法
    //[public] [abstract] 可以不用写,一般也不写。编译时自动为接口里定义的方法添加public abstract修饰符
}

接口有以下特性:

  1. 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  2. 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  3. 接口中的方法都是公有的。
  4. 编译时自动为接口里定义的方法添加public abstract修饰符
  5. Java接口里的成员变量只能是public static final共同修饰的,并且必须赋初值,可以不写public
  6. static final,编译的时候会自动添加

2.2 接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
注意:JDK1.8+可以通过添加default关键字,不必强制实现所有方法。
Java中类可以实现多个接口
格式:

[修饰符] class 类名 [implements 接口1, 接口2, 接口3..., ...]
{
   
}

2.3 接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。接口允许多继承

3. 抽象类和接口的对比

默认的方法实现:

  • 抽象类: 可以有默认的方法实现
  • 接口: 接口完全是抽象的,不存在方法的实现。但是从JDK1.8开始,接口也可以默认方法的实现。

实现:

  • 抽象类: 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的抽象方法的实现。
  • 接口: 类使用关键字implements来实现接口。
    它需要提供接口中所有声明的方法的实现.但是从JDK1.8开始,接口也可以默认方法的实现。

构造器:

  • 抽象类: 抽象类可以有构造器
  • 接口: 接口不能有构造器

与正常Java类的区别:

  • 抽象类: 除了不能实例化抽象类之外,它和普通Java类没有任何区别
  • 接口: 接囗是完全不同的类型

访问修饰符:

  • 抽象类: 抽象方法可以有pubic、private、protected等修饰符
  • 接口: 接口方法默认修饰符是public。可以有pubic、private、protected等修饰符。

main方法:

  • 抽象类: 可以有main方法并且我们可以运行它
  • 接口: 接口有main方法,因此我们可以直接运行它。

多继承:

  • 抽象类: 抽象类可以继承一个类和实现多个接口
  • 接口: 接口可以继承一个或多个其它接口

添加新方法:

  • 抽象类: 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。
  • 接口: 如果你往接口中添加方法,那么你必须改变实现该接口的类。但是从JDK1.8开始,接口也可以默认方法的实现。

相同点:

  • 都位于继承的顶端,用于被其他类实现或继承;
  • 都不能直接实例化对象;
  • 都包含抽象方法,其子类都“必须”覆写这些抽象方法;

==区别:==

  • 抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性; 接口“只能”包含抽象方法;
  • 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;
  • 抽象类是这个事物中应该具备的内容, 继承体系是一种 is..a关系 ;接口是这个事物中的额外内容,实现体系是一种 like..a关系

==二者的选用:==

  • 优先选用接口,尽量少用抽象类;
  • 需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;
  • 要实现的方法不是当前类族的必要,而是扩展,用接口.

    4. 内部类

    4.1 Java静态内部类

    • ( 可以看着两个普通类的访问关系 只是静态内部类的类名需要通过 外部类.内部类 )
      静态内部类有如下特点:
  1. 在创建静态内部类的实例时,不需要创建外部类的实例。
  2. 静态内部类中可以定义静态成员和实例成员。外部类以外的其他类需要通过完整的类名访问静态内部类中的静态成员,如果要访问静态内部类中的实例成员,则需要通过静态内部类的实例。
  3. 静态内部类可以直接访问外部类的静态成员,如果要访问外部类的实例成员,则需要通过外部类的实例去访问。
  4. 外部类可以通过静态内部类的类名直接访问静态内部类的静态成员,如果要访问静态内部类的实例成员,则需要通过静态内部类的实例去访问。

4.2 Java局部内部类

  • 局部内部类是指在一个方法(或代码块)中定义的内部类。

局部内部类有如下特点:

  1. 局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static修饰符修饰。
  2. 局部内部类只在当前方法(代码块)中有效。
  3. 局部内部类中不能定义 static 成员。
    可以有 final static修饰的静态常量
  4. 局部内部类中还可以包含内部类,但是这些内部类也不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。
  5. 在局部内部类中可以访问外部类的所有成员。
  6. 在局部内部类中只可以访问当前方法中 final 类型的参数与变量。如果方法中的成员与外部类中的成员同名,则可以使用 OuterClassName.this.MemberName的形式访问外部类中的成员。
  7. java8开始 自动为在局部内部类中被使用的变量添加final修饰符 (隐式最终)

4.3 Java匿名内部类

  • 匿名内部类是指没有类名的内部类,必须在创建时使用 new 语句来声明类
    匿名内部类有两种实现方式:
  1. 继承一个类,重写其方法。
  2. 实现一个接口(可以是多个),实现其方法。

匿名内部类有如下特点:

  1. 匿名类和局部内部类一样,可以访问外部类的所有成员。如果匿名类位于一个方法中,则匿名类只
    能访问方法中 final 类型的局部变量和参数。
  2. 匿名类中允许使用非静态代码块进行成员初始化操作。
  3. 匿名类的非静态代码块会在父类的构造方法之后被执行。

5. 枚举类型

枚举类型相当于特殊的类,经过编译之后同样产生一个class文件。

  • 枚举类型中可以定义方法(包括构造方法)、属性、静态的方法和属性、继承接口、重载覆盖等,类似于class。

枚举类型使用enum关键字 来声明类型,枚举类型的每一个枚举值(枚举属性)都是枚举类型的实例,且都是public static final类型的实例。

5.1 枚举类型的继承:

所有的枚举类型都隐含的继承自java.lang.Enum类,又因为Java是单继承的,所以一个枚举类型不能继承任何其他的类。
枚举类型因为继承了java.lang.Enum类,又因为java.lang.Enum实现了java.lang.Comparablejava.io.Serializable接口,所以枚举类型也默认实现了这两个接口。

5.2 枚举类型的构造方法:

必须是private访问权限不能使public权限

  • 这样就可以保证在枚举类型定义的外部无法使用new来创建枚举值。

使用构造方法(当然是带参数的构造方法)赋值,则必须给所有的枚举值赋值;如果写了构造方法,却没有使用其用于赋值,则会报错。

继承自父类(java.lang.Enum)的方法:

  1. ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。
  2. compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。
    Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。
  3. values()方法: 静态方法,返回一个包含全部枚举值的数组。
  4. toString()方法: 返回枚举常量的名称。
  5. valueOf()方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。
  6. equals()方法: 比较两个枚举类对象的引用。

2. ❤️Java基础专栏 - 前篇回顾

3. 💕👉 其他好文推荐

目录
相关文章
|
3月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
87 4
|
3月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
29天前
|
存储 Java Go
【Java】(3)8种基本数据类型的分析、数据类型转换规则、转义字符的列举
牢记类型转换规则在脑海中将编译和运行两个阶段分开,这是两个不同的阶段,不要弄混!
162 2
|
2月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
105 11
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
3月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
201 23
|
3月前
|
安全 Java 开发者
Java集合框架:详解Deque接口的栈操作方法全集
理解和掌握这些方法对于实现像浏览器后退功能这样的栈操作来说至关重要,它们能够帮助开发者编写既高效又稳定的应用程序。此外,在多线程环境中想保证线程安全,可以考虑使用ConcurrentLinkedDeque,它是Deque的线程安全版本,尽管它并未直接实现栈操作的方法,但是Deque的接口方法可以相对应地使用。
193 12
|
3月前
|
存储 安全 Java
Java集合框架(一):List接口及其实现类剖析
本文深入解析Java中List集合的实现原理,涵盖ArrayList的动态数组机制、LinkedList的链表结构、Vector与Stack的线程安全性及其不推荐使用的原因,对比了不同实现的性能与适用场景,帮助开发者根据实际需求选择合适的List实现。
|
3月前
|
机器学习/深度学习 安全 Java
Java 大视界 -- Java 大数据在智能金融反洗钱监测与交易异常分析中的应用(224)
本文探讨 Java 大数据在智能金融反洗钱监测与交易异常分析中的应用,介绍其在数据处理、机器学习建模、实战案例及安全隐私等方面的技术方案与挑战,展现 Java 在金融风控中的强大能力。