【Java SE语法篇】9.抽象类和接口

news2024/11/18 12:19:21

在这里插入图片描述

📚博客主页:爱敲代码的小杨.

✨专栏:《Java SE语法》

❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️

文章目录

  • 1. 抽象类
    • 1.1 抽象类的概念
    • 1.2 抽象类的语法
    • 1.3 抽象类的特性
  • 2. 接口
    • 2.1 接口的概念
    • 2.2 接口的语法规则
    • 2.3 接口的使用
    • 2.4 接口的特性
    • 2.5 实现多个接口
    • 2.6 接口之间的继承
  • 3. 抽象类和接口的区别

1. 抽象类

1.1 抽象类的概念

在面向对象的概念中,所有的对象都是通过类来描绘的,但是放过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

image-20231130230837732

1.2 抽象类的语法

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

抽象类的定义格式如下:

abstract class 抽象类名{
    属性;
    
    // 普通方法
    访问权限 返回值类型 方法名称(参数){
        return [返回值];
    }
    
    // 抽象方法,无方法体
    访问权限 abstract 返回值类型 抽象方法名称(参数);
}

从以上格式可以看出,抽象类的定义比普通类多了抽象方法,类的其他功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样

1.3 抽象类的特性

  1. 抽象类不能直接实例化对象

    image-20231201101220779

  2. 抽象方法不能是被 private 修饰的

    image-20231201101416966

  3. 抽象方法不能被finalstatic修饰,因为抽象方法要被子类重写

    image-20231201101737902

  4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰,如果一个非抽象类继承了抽象类,那么这个子类必须实现抽象类中的全部抽象方法。

    abstract class Shape {
        // 抽象方法
        public abstract  void draw();
    }
    
    abstract class A extends Shape {
        public abstract void testA();
    }
    
    class B extends A {
        @Override
        public void testA() {
    
        }
        @Override
        public void draw() {
    
        }
    }
    
  5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类

  6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

2. 接口

接口用来描述类应该做什么,而不指定它们具体应该如何做。一个类可以实现一个或多个接口。有些情况可能要求符合这些接口,主要有这种要求,就可以使用实现了这个接口的类(即实现类)的对象。

2.1 接口的概念

在Java程序设计语言中,接口不是类,而是对希望符合这个接口的类的一组需求。

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用

在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型

2.2 接口的语法规则

接口的定义格式与定义类的格式基本相同,将class 关键字换成interface关键字,就定义了一个接口。

public interface 接口名称{
    // 抽象方法
}

注意事项:

  1. 创建接口时,接口的命名一般以大写字母I开头
  2. 接口命名一般使用“形容词”词性的单词。

2.3 接口的使用

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

public class 类名 interface 接口名称{ // 可以使用,分隔,实现多个接口
    // ...
}

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

2.4 接口的特性

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

    image-20231201205108043

  2. 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是
    public abstract,其他修饰符都会报错)

    image-20231201205332074

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

    image-20231201205513841

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

    image-20231201205756142

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

image-20231201210306196

  1. 接口中不能有静态代码块和构造方法(编译错误)

    image-20231201210552916

  2. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

  3. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

2.5 实现多个接口

在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承但是一个类可以实现多个接口。下面通过类来表示一组动物。

abstract public class Animal {
    public String name;

    public Animal(String name) {
        this.name = name;
    }
}

另外我们再提供一组接口, 分别表示 “会飞的”, “会跑的”, “会游泳的”。

interface IFly {
    void fly();
}

interface IRun {
    void run();
}

interface ISwim {
    void swim();
}

接下来我们创建几个具体的动物:
猫, 是会跑的。

public class Cat extends Animal implements IRun{
    public Cat(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name + "正在用四条腿跑");
    }
}

鱼,是会游泳的

public class Fish extends Animal implements ISwim{

    public Fish(String name) {
        super(name);
    }
    
    @Override
    public void swim() {
        System.out.println(this.name + "正在游泳");
    }
}

青蛙,既能跑,又能游泳(两栖动物)

public class Fish extends Animal implements IRun,ISwim{

    public Fish(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println(this.name + "正在用两条腿跑");
    }
    
    @Override
    public void swim() {
        System.out.println(this.name + "正在游泳");
    }
}

注意:一个类实现多个接口,每个接口的抽象方法都要实现,否则类必须设置为抽象类

而鸭子即可以飞,又能跑、还可以游泳。

public class Duck extends Animal implements IFly,IRun,ISwim{

    public Duck(String name) {
        super(name);
    }

    @Override
    public void fly() {
        System.out.println(this.name + "正在用两个翅膀飞");

    }

    @Override
    public void run() {
        System.out.println(this.name + "正在用两条腿跑");
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在用两条腿游泳");

    }
}

上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口

继承表达的含义是 is-a 语义, 而接口表达的含义是 具有 xxx 特性 .

猫是一种动物,具有跑的特性。

鱼是一种动物,具有游泳的特性。

青蛙是一种,具有跑和游泳的特性。

鸭子是一种动物,具有跑、游泳和飞的特性。

这样设计有什么好处呢? 时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型,而只关注某个类是否具备某种能力.

例如:现在定义一个方法:testRun

public static void testRun(IRun iRun) {
    iRun.run();
}

在这个testRun方法内部, 我们并不关注到底是哪种动物, 只要参数是会跑的, 就行。

public static void main(String[] args) {
    testRun(new Bird("布谷"));
    testRun(new Duck("唐老鸭"));
    testRun(new Dog("旺财"));
}
// 运行结果
布谷正在用两条腿跑
唐老鸭正在用两条腿跑
旺财正在用四条腿跑

甚至参数可以不是 “动物”, 只要会跑!

class Roboot implements IRun{

    @Override
    public void run() {
        System.out.println("机器人正在用两条腿跑");
    }   
}

public class Test {
    public static void testRun(IRun iRun) {
    iRun.run();
	}
    
    public static void main(String[] args) {
        testRun(new Roboot());
    }
}

// 运行结果
机器人正在用两条腿跑

2.6 接口之间的继承

在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.

interface IRun {
    void run();
}

interface ISwim {
    void swim();
}

// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRun,ISwim{
    
}
public class Frog extends Animal implements IAmphibious{
    ...
}

通过接口继承创建一个新的接口IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法, 也需要实现 swim 方法.

接口间的继承相当于把多个接口合并在一起.

3. 抽象类和接口的区别

抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别。

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法。

如之前写的 Animal 例子. 此处的 Animal 中包含一个 name 这样的属性, 这个属性在任何子类中都是存在的. 因此此处的 Animal 只能作为一个抽象类, 而不应该成为一个接口.

public class Animal {
    public String name;

    public Animal(String name) {
        this.name = name;
    }
}
区别抽象类接口
结构组成:普通类 + 抽象方法抽象方法 + 静态常量
权限:各种权限public
子类使用:使用extends关键字继承抽象类使用implements 关键字实现接口
关系:一个抽象类可以实现若干接口接口不能继承抽象类,但是接口可以使用extends 关键字继承多个父接口
子类权限:一个子类只能继承一个抽象类一个子类可以实现多个接口

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

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

相关文章

VScode设置自动添加自定义注释及修改字体

首先安装snippet mac可以键入commanp,输出> 选择自己所需的需要自动添加的文件类型配置文件 安装自己的需要修改 "Print to console": {"prefix": "xx", // 自己键入内容"body": [ // 注释信息"// xxx …

【NI国产替代】USB‑7846 Kintex-7 160T FPGA,500 kS/s多功能可重配置I/O设备

Kintex-7 160T FPGA,500 kS/s多功能可重配置I/O设备 USB‑7846具有用户可编程FPGA,可用于高性能板载处理和对I/O信号进行直接控制,以确保系统定时和同步的完全灵活性。 您可以使用LabVIEW FPGA模块自定义这些设备,开发需要精确定时…

canvas创建图像数据,并在画布上展示

查看专栏目录 canvas示例教程100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

Python学习从0到1 day4 python格式化输出和输入方法

其实我不是我,我是青山辽阔 ——24.1.14 一、百分号形式的格式化输出 1.普通输出 #1.定义一些变量 name 陈浩南 age 25 address 广州市天河区#2.变量的输出(普通输出) print(name) print(age) print(address)#3.Python中,还允…

【矩阵快速幂】封装类及测试用例及样例

作者推荐 视频算法专题 通俗的说&#xff0c;就是矩阵的乘方。 封装类 核心代码 class CMat { public:// 矩阵乘法static vector<vector<long long>> multiply(const vector<vector<long long>>& a, const vector<vector<long long>…

八:分布式锁

1、为什么要使用分布式锁 锁是多线程代码中的概念&#xff0c;只有多任务访问同一个互斥的共享资源时才需要锁。单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。应用是分布式集群&#xff0c;属于多JVM的工作环境&#xff0c;JVM之间已经无法通过…

【Golang开源项目】Golang高性能内存缓存库BigCache设计与分析

项目地址 BigCache 是一个快速&#xff0c;支持并发访问&#xff0c;自淘汰的内存型缓存&#xff0c;可以在存储大量元素时依然保持高性能。BigCache将元素保存在堆上却避免了GC的开销。 背景介绍 BigCache的作者在项目里遇到了如下的需求&#xff1a; 支持http协议支持 10…

【RT-DETR改进涨点】为什么YOLO版本的RT-DETR训练模型不收敛的问题

前言 大家好&#xff0c;我是Snu77&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 其中提到的多个版本ResNet18、ResNet34、ResNet50、ResNet101为本人根据RT-…

Linux|centos7操作系统|VMware虚拟机安装水星免驱USB网卡8188gu记录

引言&#xff1a; 最近对于嵌入式系统比较感兴趣&#xff0c;因此&#xff0c;计划先使用VMware workstation虚拟机试一试Linux系统下的网卡驱动安装 这不试不知道&#xff0c;一试吓一跳&#xff0c;发现Linux下的驱动安装还是比较麻烦的&#xff0c;下面将就本次的Linux系统…

详解SpringCloud微服务技术栈:强推!源码跟踪分析Ribbon负载均衡原理、Eureka服务部署

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;详解SpringCloud微服务技术栈&#xff1a;认识微服务、服务拆分与远程调用 &#x1f4da;订阅专栏&#xff1a;微服务技术全家桶…

【LangChain学习之旅】—(6) 提示工程(下):用思维链和思维树提升模型思考质量

【LangChain学习之旅】—&#xff08;6&#xff09; 提示工程&#xff08;下&#xff09;&#xff1a;用思维链和思维树提升模型思考质量 什么是 Chain of ThoughtFew-Shot CoTZero-Shot CoTChain of Thought 实战CoT 的模板设计程序的完整框架Tree of Thought总结 Reference&a…

UE5 伤害数字跳出

学习视频 大体思路&#xff1a; 1.创建一个控件蓝图。 播放动画&#xff0c;K透明度&#xff0c;文本位置。 2.创建一个控件组件。 类默认值中设置。 3.在位置处创建组件实例 自定义事件略。

NVIDIA Isaac Sim 入门教程(一)

系列文章目录 前言 一、 NVIDIA Omniverse™ Isaac Sim 是什么&#xff1f; NVIDIA Omniverse™ Isaac Sim 是一款适用于 NVIDIA Omniverse™ 平台的机器人仿真工具包。Isaac Sim 具有构建虚拟机器人世界和实验的基本功能。它为研究人员和从业人员提供了创建稳健、物理精确的仿…

无法解析服务器的名称或地址/Wsl/0x80072eff/win10 WSL2问题解决Wsl 0x800701bc/Wsl:0x80041002

无法解析服务器的名称或地址 和 Wsl/0x80072eff 1.连VPN&#xff0c;推荐的VPN如下。(如一直显示无法连接&#xff0c;则推荐使用VPN) Anycast加速器 (any4ga.com) 优点&#xff1a;无限GB 缺点&#xff1a;较贵&#xff0c;通过银行卡充值9折后的价格是每月45元左右 …

JVM:双亲委派机制类加载器

JVM&#xff1a;双亲委派机制 1. 例子2. 类加载器总结3. 类加载过程4. 双亲委派模型的执行流程&#xff1a;5. 双亲委派模型的好处 1. 例子 Java运行时环境有一个java.lang包&#xff0c;里面有一个ClassLoader类 我们自定义一个String类在java.lang包下&#xff0c;下面的…

WEB 3D技术 three.js 点光源

本文的话 我们来设置一下点光源 点光源其实最直观的就是可以做萤火虫 也可以做星光 点点的效果 我们可以直接在官网中搜索 Pointlight 大家可以在官网这里看一下 其实 SpotLight 聚关灯中的属性 Pointlight 点光源也有的 我们先编写代码如下 import ./style.css import * a…

MySQL之单表查询

素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varchar(10) NO…

【Git】本地仓库管理远程库(GitHub)——clone(下载)、commit(添加到本地仓库)、push(提交到远程仓库)、pull(拉取)操作

目录 使用远程仓库的目的将本地仓库同步到git远程仓库 1.克隆远程仓库(clone)2.新建一个文件3.将工作区的文件添加到暂存区4.将暂存区的文件添加到本地仓库(commit)5.提交(同步)到远程仓库(push)6.远程库拉取到本地库(pull)7.团队协作开发和跨团队协作开发(开源项目) 使用远程…

PTA(浙大版《C语言程序设计(第3版)》题目集

PTA(浙大版《C语言程序设计&#xff08;第3版&#xff09;》题目集 学习C语言程序设计的PTA题目 目录 PTA(浙大版《C语言程序设计&#xff08;第3版&#xff09;》题目集PTA(浙大版《C语言程序设计&#xff08;第3版&#xff09;》题目集) 习题2-1 求整数均值 (10 分)输入格式:…

大型语言模型综述/总结 LLM A Survey of Large Language Models

A Survey of Large Language Model AbstractINTRODUCTIONOVERVIEW背景LLM的新兴能力LLM的关键技术GPT 系列模型的技术演进 大语言模型资源公开可用的模型检查点或 API常用语料库代码库资源 预训练数据收集架构 论文标题&#xff1a;A Survey of Large Language Model 论文地址&…