揭秘:抽象类与接口之间的区别与意义

抽象类(Abstract Class)和接口(Interface)在Java等面向对象编程语言中都是用来定义对象的抽象行为,但它们之间存在一些重要的区别和不同的使用场景。以下是它们之间的主要区别和意义:
  1. 实现方式
    • 抽象类可以包含抽象方法和非抽象方法(即实现的方法)。
    • 接口只能包含抽象方法(从Java 8开始,接口也可以包含默认方法和静态方法,但默认方法必须有具体实现)。
  2. 继承与实现
    • 一个类只能继承一个抽象类(Java中的单继承原则),但可以实现多个接口(Java支持多重实现)。
    • 通过实现多个接口,一个类可以具有来自不同接口的行为,从而增强了类的功能性和灵活性。
  3. 字段
    • 抽象类可以包含字段(成员变量),无论是静态的还是非静态的。
    • 接口中定义的字段都是隐式静态和最终的(static and final),即它们实际上是常量。
  4. 构造函数
    • 抽象类可以有构造函数,用于初始化抽象类的状态。
    • 接口不能有构造函数。
  5. 设计目的
    • 抽象类通常用于表示一种对象的模板,其中某些方法的具体实现由子类来提供。抽象类可以作为一种类型,用于定义该类型对象共有的属性和行为。
    • 接口通常用于定义对象之间的契约或协议,它指定了一个对象必须遵循的方法列表,但不提供这些方法的实现。接口主要用于实现多重继承,即允许一个类具有来自多个源的行为。
  6. 扩展性
    • 抽象类在后续版本中可以通过添加新的抽象方法或实现新的非抽象方法来扩展其功能,但这可能会影响到已经存在的子类(如果它们没有提供新方法的实现)。
    • 接口在后续版本中可以通过添加新的抽象方法来扩展其功能,而不需要修改已经实现了该接口的类(只要它们实现了新添加的方法)。
  7. 使用场景
    • 当你需要一种类型来定义对象的共有属性和行为,并且希望这些行为中有一部分可以有默认实现时,应该使用抽象类。
    • 当你需要定义一组方法的契约,并且这些方法的实现将由不同的类来提供时,应该使用接口。接口也常用于定义插件式架构或框架中的扩展点。

抽象类和接口都是面向对象编程中非常重要的概念,它们各自有其独特的作用和使用场景。在选择使用抽象类还是接口时,需要根据具体的需求和设计目标来决定。

代码举例:

// 抽象类  
abstract class Animal {  // 字段  private String name;  // 构造函数  public Animal(String name) {  this.name = name;  }  // 抽象方法  public abstract void makeSound();  // 非抽象方法(具体实现)  public void setName(String name) {  this.name = name;  }  public String getName() {  return name;  }  
}  // 抽象类的子类  
class Dog extends Animal {  // 实现父类的抽象方法  @Override  public void makeSound() {  System.out.println("Woof!");  }  
}  // 使用抽象类  
public class AbstractClassDemo {  public static void main(String[] args) {  Dog dog = new Dog("Buddy");  dog.makeSound(); // 输出 "Woof!"  System.out.println(dog.getName()); // 输出 "Buddy"  }  
}
// 接口  
interface Shape {  // 常量(接口中的字段默认为 public static final)  int NUMBER_OF_SIDES = 0;  // 抽象方法  void draw();  // Java 8 开始的默认方法  default void resize() {  System.out.println("Resizing shape...");  }  
}  // 接口的实现类  
class Circle implements Shape {  // 实现接口中的抽象方法  @Override  public void draw() {  System.out.println("Drawing a circle...");  }  
}  // 使用接口  
public class InterfaceDemo {  public static void main(String[] args) {  Circle circle = new Circle();  circle.draw(); // 输出 "Drawing a circle..."  circle.resize(); // 输出 "Resizing shape..."  }  
}

关键点说明
在Animal抽象类中,定义了一个抽象方法makeSound()和一个具体实现的方法setName()和getName()。子类Dog需要实现makeSound()方法。

在Shape接口中,我定义了一个常量NUMBER_OF_SIDES(尽管它没有实际意义,因为圆形没有边)和一个抽象方法draw()。接口还可以包含默认方法(如resize()),该方法在接口中提供了默认实现。

类Circle实现了Shape接口,并提供了draw()方法的具体实现。由于resize()是默认方法,Circle类不需要实现它。

通过这些示例,可以看到抽象类和接口在定义对象的抽象行为时的作用和区别。抽象类通常包含一些具体的实现,而接口则完全由抽象方法组成(尽管可以有默认方法和静态方法)。接口提供了一种更灵活的扩展机制,允许类实现多个接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/834630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解网络原理5----HTTP协议

文章目录 一、HTTP协议格式二、HTTP请求2.1 URL 基本格式2.2 URL encode2.3 "方法" (method)2.4 认识请求 "报头" (header) 三、HTTP 响应3.1 "状态码" (status code) 四、HTPPS工作过程(经典面试题) 提示:以下…

【全开源】Java U U跑腿同城跑腿小程序源码快递代取帮买帮送源码小程序+H 5+公众号跑腿系统

特色功能: 智能定位与路线规划:UU跑腿小程序能够利用定位技术,为用户提供附近的跑腿服务,并自动规划最佳路线,提高配送效率。订单管理:包括订单查询、订单状态更新、订单评价等功能,全行业覆盖…

awk小尝试2(随手记)

文章目录 需求1解法 需求2解法(3种-grep/sed/awk) 需求3解法 需求1 使用hostname -I创建文件名 echo hostname -I.txt 10.0.0.124 .txt # 需要注意,这里的.txt前有一个空格,需要去掉,不然就是两个文件名解法 echo h…

Lua 零基础入门

Lua 1.Lua是什么? 1.1 Lua的历史 Lua是由Roberto Ierusalimschy、Luiz Henrique de Figueiredo和Waldemar Celes于1993年创建的,当时他们是巴西里约热内卢天主教大学计算机图形技术组(Tecgraf)的成员。在开发Lua之前&#xff0…

智慧营销的未来:中国AIGC技术的演进与应用 #未来是现在的趋势#

📑前言 随着人工智能(AI)技术的蓬勃发展,尤其是在营销技术(MarTech)领域,AIGC(AI Generated Content)技术在中国市场的应用和影响日益显著。2023年,中国在AIG…

一款好用的memcached的内存使用分析工具

文章目录 简介1.打印帮助信息2.查看memcached的基础信息3.查看memcached的StatsSizes分布4.查看memcachd中slab的使用情况5.查看memcachd中slab的置换率、回收及内存使用率 简介 xmc是一款分析memcached内存使用情况的工具,通过读取memcached的状态,包括…

柯里化与无参装饰器

柯里化 柯里化的概念:柯里化(Currying)在Python中是一种编程技术,它将原本接受多个参数的函数转换为一系列接受单个参数的函数。这种方法以逻辑学家Haskell Curry的名字命名。 简而言之就是将一次函数调用变成先放入一个参数得到…

Android(一)

坏境 java版本 下载 Android Studio 和应用工具 - Android 开发者 | Android Developers 进入安卓官网下载 勾选协议 next 如果本地有设置文件,选择Config or installation folder 如果本地没有设置文件,选择Do not import settings 同意两个协议 耐…

车载测试系列:车载蓝牙测试(三)

HFP测试内容与测试方法 2.3 接听来电:测试手机来电时,能否从车载蓝牙设备和手机侧正常接听】拒接、通话是否正常。 1、预置条件:待测手机与车载车载设备处于连接状态 2、测试步骤: 1)用辅助测试机拨打待测手机&…

LeetCode-460. LFU 缓存【设计 哈希表 链表 双向链表】

LeetCode-460. LFU 缓存【设计 哈希表 链表 双向链表】 题目描述:解题思路一:一张图秒懂 LFU!解题思路二:精简版!两个哈希表,一个记录所有节点,一个记录次数链表【defaultdict(new_list)&#x…

不要以为C语言很独特!

学习C语言想当然以为那些简洁自由的语法是C语言独创,事实上,C语言是从B语言扩展而来,很多特性都可以在B语言中找到,B语言是BCPL的简化版,BCPL来自CPL,CPL借鉴了计算机鼻祖级别编程语言ALGOL, 而和ALGOL同时…

数字图像处理基于opencv-python 入门demo1

数字图像处理 随着人工智能发展,数字图像处理显得尤为作用,体现在如何让计算机代替人眼进行识别检测一些物体,进而对一些生活场景进行监控,控制以及处理。 图像的读取 """ Time : 2024/4/28 22:14 Author :…

vcs覆盖率合并和查看

1 vcs编译增加覆盖率选项 1)编译的时候增加的选项 VCS增加如下选项 vcs ${vcs_elab_opts} xil_defaultlib.${top} xil_defaultlib.glbl -o ${top}_simv \ -cm linecondfsmbranchtgl \ -cm_name ${top} \ -cm_dir ./${top}.vdb 上面的vcs…

6-3 Deque

作者 陈越 单位 浙江大学 A "deque" is a data structure consisting of a list of items, on which the following operations are possible: Push(X,D): Insert item X on the front end of deque D.Pop(D): Remove the front item from deque D and return it.…

LeetCode例题讲解:3005最大频率元素计数

给你一个由 正整数 组成的数组 nums 。 返回数组 nums 中所有具有 最大 频率的元素的 总频率 。 元素的 频率 是指该元素在数组中出现的次数。 示例 1: 输入:nums [1,2,2,3,1,4] 输出:4 解释:元素 1 和 2 的频率为 2 &#xf…

OpenHarmony实战开发——WLAN驱动框架介绍及适配方法

1. WLAN 驱动框架概述 WLAN 是基于 HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移、自适应器件差异、模块化拼装编译等功能。从而降低 WLAN 驱动开发的难度,减少 WLAN 驱动移植和开发的工作量。 本文主要分析 WLAN 驱…

c++ upper_bound和lower_bound

upper_bound和lower_bound 是C的STL(标准模板库)中的两个函数,用于在一个有序的容器中查找特定元素的上界和下界。 upper_bound函数的作用是在一个有序容器中查找大于某个值val的第一个位置。它返回一个迭代器,该迭代器指向容器中…

mac重装pycharm失败

更新重装新版本后失败 试了好多个版本都不行 清除掉原来的pycharm残余信息后可以装上 检查是否有以下残留信息 rm -rf ~/Library/Application Support/JetBrains rm -rf ~/Library/Application Support/PyCharm*# Configuration rm -rf ~/Library/Preferences/PyCharm* # Cac…

Windows下安装人大金仓数据库

1、点击安装包进行安装 2、双击进行安装 3、点击确定 4、接着选择下一步 5、勾选接收 6、选择授权文件 7、显示授权文件信息 8、选择安装位置 9、点击安装 10、点击下一步 11、正在进行安装 12、设置密码。123456 13、系统正在进行配置 14、安装完成 15、登…

C 深入指针(3)

目录 一、关于数组名 1 数组名的理解 2 数组名 与 &数组名 的区别 二、使用数组访问指针 三、一维数组传参的本质 四、二级指针 五、指针数组 六、指针数组模拟二维数组 一、关于数组名 1 数组名的理解 //VS2022 x64 #include <stdio.h> int main() {int …