【Java 学习】:抽象类接口

✨                                                 人逢喜事精神爽,月到中秋分外明       🌏 

📃个人主页:island1314

🔥个人专栏:java学习

⛺️  欢迎关注:👍点赞 👂🏽留言 😍收藏  💞 💞 💞


1. 抽象类

1.1 抽象类是什么

💢💢在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。

我们先来看一个简单的例子🌰

// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Animal {// 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体abstract void eat();// 抽象类也是类,也可以增加普通方法和属性public double getArea(){return area;}protected double area; // 面积
}

初看上面是不是没啥问题,但是当我们对这个类进行实例化的时候,就会发现:

像这样的类是不是就没有包含足够的信息来描绘一个具体的对象,因此也就不能直接去实例化对象了。那我们应该怎么解决这个实例化问题呢?

// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Animal {// 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体abstract void eat();// 抽象类也是类,也可以增加普通方法和属性public double getArea(){return area;}protected double area; // 面积
}
public class Test{public static void main(String[] args) {Animal animal = new Animal() {@Overridevoid eat() {System.out.println("重写");}};}
}

只需要对 abstract类的抽象方法实例化之后进行重写即可。

注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法

1.2 抽象类特性

🍉抽象类不能直接实例化对象,无法创建对象,抽象类是被子类来继承的

Animal animal = new Animal();
// 编译出错
Error:(30, 23) java: Animal是抽象的; 无法实例化

🥑抽象方法不能是 private 的

abstract class Animal {abstract private void eat(); //抽象方法不能是 private 的
}
// 编译出错
Error:(4, 27) java: 非法的修饰符组合: abstract和private

🥝抽象方法不能被final和static修饰,因为抽象方法要被子类重写

public abstract class Animal {abstract final void methodA();abstract public static void methodB();
}
// 编译报错:
// Error:(20, 25) java: 非法的修饰符组合: abstract和final
// Error:(21, 33) java: 非法的修饰符组合: abstract和static

🍋‍🟩抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰

abstract class Animal {abstract void eat();// 抽象类也是类,也可以增加普通方法和属性public double getArea(){return area;}protected double area; // 面积
}class Dog extends Animal{@Overridevoid eat() { // 重写}
}abstract class Cat extends Animal{}

🥬其他特性:

  • 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
  • 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

1.3 抽象类的应用

🍅那既然一个类不能直接实例化,那这种抽象类存在的意义是什么呀🤔?我们接着往下看

🍅抽象类存在的一个最大意义就是被继承,当被继承后就可以利用抽象类实现多态。

代码示例如下:

class Dog extends Animal{@Overridevoid eat() {System.out.println("小狗吃东西");}
}public class Test {public static void main(String[] args) {//Animal animal = new Animal(); // 抽象类虽然无法直接实例化// 但可以把一个普通类对象传给一个抽象类的引用呀,即父类引用指向子类对象Animal animal = new Dog(); // 这称作:向上转型/*Dog dog = new Dog();Animal animal = dog; // 这是向上转型的另一种写法*/animal.eat();         // 通过父类引用调用被子类重写的方法}
}

向上转型的具体,我们之前在多态那篇博客【Java 基础】:三大特征之多态-CSDN博客那就已经讲过,就不过多讲解了,只需要知道向上转型是:父类引用指向子类对象

1.4 抽象类的总结

抽象类是类和类之间的共同特征,将这些共同特征进一步形成抽象类,由于类本身不存在,所以抽象类无法创建对象。
类到对象是实例化,对象到类是抽象
抽象方法不能被 final 修饰,因为抽象方法就是被子类实现的

  • 采用 abstract 关键字定义的类就是抽象类,采用 abstract 关键字定义的方法就
    是抽象方法
  • 抽象的方法只需在抽象类中,提供声明,不需要实现
  • 如果一个类中含有抽象方法,那么这个类必须定义成抽象类。抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中
  • final和abstract不能同时同时使用,这两个关键字是对立的
  • 抽象方法不能被private修饰
  • 抽象类的子类可以是抽象类。也可以是非抽象类
  • 一个非抽象的类,继承抽象类,必须将抽象类中的抽象方法进行覆盖/重写/实现

抽象方法表示没有实现的方法,没有方法体的方法

  1. 没有方法体,以分号结尾
  2. 前面的修饰符列表中有abstract关键字,比如public abstract void dosome();

但是不能说java语言中没有方法体的方法都是抽象方法。
因为Object类中就有很多方法都没有方法体,都是以“;”结尾的,但他们都不是抽象方法

2. 接口 

2.1 接口是什么

🍑抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(Interface)🤔。

📝接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成😎。

  • 接口是一种“引用数据类型”,完全抽象的,支持多继承,且一个接口可以继承多个接口,只有常量+抽象方法
  • 所有的元素都是public修饰的,抽象方法的public abstract可以省略,常量的public static final可以省略,方法不能有方法体

如何定义一个接口呢?下面我们来看一个栗子🌰

// 定义格式如下:
//[修饰符列表] interface 接口名{}// 实例:
public interface Test{// 定义变量int a = 10;      // 接口当中的成员变量默认都是public static final// 抽象方法public abstract void metho(); // public abstract 是固定搭配,可以不写void method();  //  接口当中的成员方法默认都是public abstract, 更推荐用第二种来定义方法
}

提示:

  1.  创建接口时, 接口的命名一般以大写字母 I 开头.
  2.  接口的命名一般使用 "形容词" 词性的单词.
  3.  阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.

2.2 接口的使用 

接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法

/* 语法格式 */
/* class 类名称 implements 接口名称{
// ...
} *///实例
interface USB {void openDevice(); // 默认是public的void closeDevice(); // 默认是public的
}class Mouse implements USB {@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {}// ...
}

注:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。

2.3 接口的特性

🍉接口类型是一种引用类型,但是不能直接new接口的对象

public class TestUSB {public static void main(String[] args) {USB usb = new USB();}
}
// Error:(10, 19) java: USB是抽象的; 无法实例化

🥑接口中每一个方法都是public的抽象方法,所以不能有方法体。 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)

//定义抽象方法的时候可以省略修饰符public abstract
public interface USB {// Error:(4, 18) java: 此处不允许使用修饰符privateprivate void openDevice();void closeDevice();
}

🥝接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

public interface USB {void openDevice();// 编译失败:因为接口中的方式默认为抽象方法// Error:(5, 23) java: 接口抽象方法不能带有主体void closeDevice(){System.out.println("关闭USB设备");}
}

🍋‍🟩重写接口中方法时,不能使用默认的访问权限

/* 语法格式 */
/* public class 类名称 implements 接口名称{
// ...
} *///实例
interface USB {void openDevice(); // 默认是public的
}class Mouse implements USB {@Overridevoid openDevice() { //解决:函数前加个权限 public 即可System.out.println("打开鼠标");}
}
// 编译报错,重写USB中openDevice方法时,不能使用默认修饰符
// 正在尝试分配更低的访问权限; 以前为public

🍈接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量

interface USB {double brand = 3.0; // 默认被:final public static修饰void openDevice();void closeDevice();
}
public class Test {public static void main(String[] args) {System.out.println(USB.brand); // 可以直接通过接口名访问,说明是静态的// 编译报错:Error:(12, 12) java: 无法为最终变量brand分配值USB.brand = 2.0; // 说明brand具有final属性,无法被再次赋值}
}

🍀支持多继承,且一个接口可以继承多个接口,每一个interface 都会生成一个class后缀名的文件 

interface a{
}interface b extends a{
}interface c extends a,b{
}

🥬其他特性:

  • 接口中不能有静态代码块和构造方法
  • 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
  • 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
  • jdk8中:接口中还可以包含default方法。

2.4 接口的应用

 通过接口实现多态

🍌刚才我们是用抽象类来实现多态,那么现在我们来尝试使用接口去实现多态😎

interface Animal{int a = 10;   //接口当中的成员变量默认都是public static finalint b = 23;void eat();  //接口当中的成员方法一般只能是抽象方法,默认是public abstract(JDK1.8以前)default void show() {System.out.println("接口中的其他方法");//接口中的其他方法也可以实现,但要用default修饰}public static void test() {System.out.println("这是接口当中的一个静态的方法");}
}// 一个普通的类要想实现接口,可以用implement,
//因为接口也是抽象方法的,所以实现接口的这个类也要重写抽象方法
class Dog implements Animal{@Overridepublic void eat() {System.out.println("小狗");}
}class Cat implements Animal{@Overridepublic void eat() {}
}public class Test{public static void main(String[] args) {Animal[] animals = {new Dog(),new Cat()};for(Animal animal: animals){animal.eat();}}
}

2.5 接口总结

  1. 接口是抽象化的,不能实例化
  2. 接口抽象方法必须实现,默认修饰 public abstract
  3. 接口属性是被 public static final 修饰,静态的、不可修改的
  4. 接口没有构造方法
  5. 接口有静态方法,含有方法体,主要特点是使用接口名调用静态方法
  6. 接口有默认方法,含有方法体,主要目的是为了扩展性和复用性

📖 总结

Java中接口和抽象类的定义语法分别为interface与abstract关键字。

相同点:

  • 都不能被实例化 ,接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。

不同点:

  1. 抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;接口中的方法默认使用public修饰
  2. 抽象类可有成员变量,接口只能有 public static final 修饰的常量:接口成员变量默认为public static final,必须赋初值,不能被修改。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;
  3. 实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
  4. 接口强调特定功能的实现,而抽象类强调所属关系。
  5. 抽象类可有构造函数,接口没有构造函数:抽象类可以包含方法、构造方法,方法可以实现,但是构造方法不能用于实例化,主要用途是被子类调用。接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体。

💞 💞 💞那么本篇到此就结束,希望我的这篇博客可以给你提供有益的参考和启示,感谢大家支持!!!祝大家天天开心

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

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

相关文章

【代码】使用c#实现串口通信的基础模板

一、分享代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;using System.IO.Ports; using…

【环境问题】清除僵尸进程 | 深度学习任务中止但是GPU仍在占用

我一般遇到这种是本地网络意外中断了,程序不见了,但是GPU仍在占用。 1.确认GPU显存: 终端输入 nvidia-smi 查看显存使用情况: 2.查看所有进程: 输入fuser -v /dev/nvidia* 查看进程。如果出现bash: fuser: command no…

数据结构——链表(短小精悍版)

使用链表结构可以克服数组链表需要预先知道数据大小的缺点 链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。 但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。 单向链表: 一个…

【kafka】生产者

1. 主要参数: **bootstrap.servers:**该参数用来指定生产者客户端连接Kafka集群所需的broker地址清单,具体的内容格式为host1:port1,host2:port2,可以设置一个或多个地址,中间以逗号…

《Google软件测试之道》笔记

介绍 GTAC:Google Test Automation Conference,Google测试自动化大会。 本书出版之前还有一本《微软测试之道》,值得阅读。 质量不是被测试出来的,但未经测试也不可能开发出有质量的软件。质量是开发过程的问题,而不…

ROS第五梯:ROS+VSCode+C++单步调试

解决问题:在ROS项目中进行断点调试。 第一步:创建一个ROS项目或者打开一个现有的ROS项目。 第二步:修改c_cpp_properties.json 增加一段命令: "compileCommands": "${workspaceFolder}/build/compile_commands.json"第三…

线结构光测量系统标定--导轨

光平面标定原理可查看之前的博文《光平面标定》,光条中心提取可参考线结构光专栏光条中心提取系列的文章,相机标定参考相机标定专栏中的博文。(欢迎进Q群交流:874653199) 线结构光测量系统(指一个线结构光传感器与一个…

rocky9虚拟机配置双网卡的详细过程

编辑虚拟机配置->添加->选择网络适配器->确认->打开虚拟机 1.ip add查看第二个网卡的名称,我这里是ens36 2.cd到网卡的配置文件目录 cd /etc/NetworkManager/system-connections/ ls3.复制一份网卡的配置文件并改名为ens36.nmconnection(根据自己的第…

计算机网络(运输层)

物理层、数据链路层以及网络层共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机与主机之间的通信。 实际上在计算机网络中进行通信的真正实体事位于通信两端主机中的进程。 运输层的任务就会是提供运行在不同主机上的应用进程提供直接的通信服务&…

pybind11 学习笔记

pybind11 学习笔记 0. 一个例子1. 官方文档1.1 Installing the Library1.1.1 Include as A Submodule1.1.2 Include with PyPI1.1.3 Include with Conda-forge 1.2 First Steps1.2.1 Separate Files1.2.2 PYBIND11_MODULE() 宏1.2.3 example.cpython-38-x86_64-linux-gnu.so 的…

常见 HTTP 状态码详解与Nginx 文件上传大小限制

在我们日常使用 Nginx 搭建网站或应用服务时,可能会遇到很多与文件上传和请求响应相关的问题。今天我们就来聊聊 如何限制文件上传的大小,并介绍一些常见的 HTTP 状态码 及其在 Nginx 中的处理方式。 一、文件上传大小限制 有时,我们需要限…

从入门到精通,玩转Python的print函数(探索Python print函数的隐藏功能)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 基础用法参数详解示例📝 高级用法自定义分隔符和结束符输出到文件追加模式📝 覆盖打印与进度条简单覆盖打印动态进度条示例代码⚓️ 相关链接 ⚓️📖 介绍 📖 刚开始学习编程时,我们接触到的第一个方…

【初阶数据结构】一文讲清楚 “堆” 和 “堆排序” -- 树和二叉树(二)(内含TOP-K问题)

文章目录 前言1. 堆1.1 堆的概念1.2 堆的分类 2. 堆的实现2.1 堆的结构体设置2.2 堆的初始化2.3 堆的销毁2.4 添加数据到堆2.4.1 "向上调整"算法 2.5 从堆中删除数据2.5.1 “向下调整”算法 2.6 堆的其它各种方法接口函数 3. 堆排序3.1 堆排序的代码实现 4. TOP-K问题…

微软Office全家桶再爆办公革命,o1模型加持重塑十亿人工作流!1句话生成PPT+自定义智能体

颠覆全球十亿打工人的Office办公全家桶,昨夜迎来重磅升级! 在微软Copilot第二弹发布会上,CEO纳德拉官宣,「用AI构思,共同协作的全新工作流——WebWorkPages正式开启」。 全程半小时,每一幕都在透露着&…

GPT代码记录

#include <iostream>// 基类模板 template<typename T> class Base { public:void func() {std::cout << "Base function" << std::endl;} };// 特化的子类 template<typename T> class Derived : public Base<T> { public:void…

基于JDK1.8和Maven的GeoTools 28.X源码自主构建实践

目录 前言 一、GeoTools与Jdk的版本关系 1、GeoTools与Jdk版本 2、编译环境简介 二、使用Maven编译GeoTools28.X 1、GeoTools28.x 2、Maven的完整编译 3、构建时的问题 三、总结 前言 想要学习和掌握一个开源软件或者项目&#xff0c;源码是我们主要学习的内容。学习开…

JDBC笔记

文章目录 准备MySQL数据的建立和建表 idea 建工程和模块设置属性配置文件编写JDBC代码URL的设置JDBC 代码配置文件 准备MySQL 数据的建立和建表 idea 建工程和模块 设置属性配置文件 编写JDBC代码 URL的设置 JDBC 代码 package com.yanyu;import java.sql.*; import java.util…

vue2.0+ts注册全局函数和几个递归查找

vue2.0ts注册全局函数和几个递归查找 一、main.ts 一、main.ts // 定义你的全局函数,判断是否有按钮权限 interface Item {label: string;checked: number;[k: string]: any; } // 获取按钮时候权限 function globalLable(arr: Item[], label: string): boolean {for (const i…

硬件基础知识

驱动开发分为&#xff1a;裸机驱动、linux驱动 嵌入式&#xff1a;以计算机技术为基础&#xff0c;软硬结合的、可移植、可剪裁的专用计算机 单片机最小单元&#xff1a;vcc gnd reset 晶振 cpu --- soc :system on chip 片上外设 所有的程序都是在soc&#xff08;cpu&…