Java SE(10)——抽象类接口

news2025/5/10 10:56:57

1.抽象类

1.1 概念

在之前讲Java SE(6)——类和对象(一)的时候说过,所有的对象都可以通过类来抽象。但是反过来,并不是说所有的类都是用来抽象一个具体的对象。如果一个类本身没有足够的信息来描述一个具体的对象,而是用于定义一个模板,为子类提供通用的属性和方法,这样的类就是抽象类
在这里插入图片描述

1.2 语法规则

在Java中,被abstract修饰的类就是抽象类;被abstract修饰的方法就是抽象方法

//抽象类
public abstract class AbstractClass {
    //抽象方法
    public abstract void abstractMethod();
}
  • 1.抽象类不能直接实例化,它只能作为其他类的父类 在这里插入图片描述
  • 2.抽象方法是一种没有具体实现的方法,即没有方法体 在这里插入图片描述
  • 3.抽象类中也可以定义普通成员变量/普通成员方法/构造方法。换言之,抽象类中不一定有抽象方法,但是抽象方法所在的类一定是抽象类
    在这里插入图片描述
    在这里插入图片描述
  • 4.abstract只能修饰类和方法,没有抽象变量这个概念 在这里插入图片描述
  • 5.抽象方法不能用private/static/final修饰 在这里插入图片描述
问题:既然抽象类无法直接实例化对象,那么抽象类真正的作用是什么?
在上面讲概念和语法规则的时候说过,抽象类只能作为父类被其他类继承,给子类提供一个模板并由子类来实现。

1.3 抽象类的实现

public abstract class Shape {
    //普通成员变量
    public int width;
    public int length;
    //普通方法
    public void hello(){
        System.out.println("hello shape");
    }
    //构造方法
    public Shape(int width, int length) {
        this.width = width;
        this.length = length;
    }
    public abstract void draw();
}
public class Circle extends Shape {
    public Circle(int width, int length) {
        super(width, length);
    }
    @Override
    public void draw() {
        System.out.println("draw circle:" + this.width + " * " + this.length);
    }
    @Override
    public void hello(){
        System.out.println("hello circle");
    }
}
public class Test {
    public static void main(String[] args) {
        //无法直接实例化抽象类
        /*Shape shape = new Shape();*/
        Shape circle = new Circle(10,10);
        circle.draw();
        circle.hello();
    }
}

运行结果:
draw circle:10 * 10
hello circle

  • 1.当某一个类(称为实现类)继承抽象类时,该实现类必须重写抽象类中的所有抽象方法 (这也是抽象方法不能使用private/static/final修饰的根本原因)在这里插入图片描述
  • 2.如果是抽象类A继承抽象类B,则不需要重写父类中的抽象方法。直到有实现类C来继承抽象类A,那么实现类C要重写A和B中的所有抽象方法 在这里插入图片描述

1.4 意义

仔细观察上述代码,抽象类和实现类之间构建了继承关系,发生了向上转型/方法重写。但是普通类和普通类之间好像也可以完成上述操作,换言之,抽象类能完成的功能普通类也可以。那么抽象类存在的意义是什么?
还是以上述代码为例,此时的需求是画一个circle。假设父类使用普通类,如果用户一不小心将父类直接实例化,那么此时调用draw()方法就无法画一个circle出来;再假设父类使用抽象类,如果用户直接实例化父类是会报错的,而且子类如果不重写抽象方法也是会报错的,这就是抽象类在提醒用户。使用抽象类相较于使用普通类,在特定场景下多了一层校验效果

2.接口

2.1 概念

在日常生活中,经常听到接口这个东西。比如:电脑的USB-A接口,既可以连接键盘,又可以连接鼠标、耳机等等,只要是适配UEB协议的设备都可以连接
在这里插入图片描述
通过这些例子可以简述一下接口的作用:接口就是公共的行为规范标准。在实现某些功能时只要符合该规范标准就行了
在Java中,接口可以看作是多个类的公共规范,是一种引用数据类型

2.2 语法规则

定义接口需要借助interface关键字

public interface 接口名称{
}
  • 1.接口中的方法默认使用public abstract修饰,所以定义方法时,建议不要再手动添加修饰词
    在这里插入图片描述
  • 2.接口中的变量默认使用public static final修饰 在这里插入图片描述
  • 3.接口中不能定义构造方法 在这里插入图片描述
  • 4.在JDK8及以后,接口中可以定义静态方法和default方法 在这里插入图片描述
    default方法时接口中独有的方法,等会儿仔细说说default方法的作用

2.3 接口的实现

接口和抽象类一样,也不能直接实例化对象,只能由某个具体的类来实现。并且在Java SE(8)——继承中讲过,一个类只能拥有一个父类,但是一个类可以实现多个接口

类实现接口使用的是implements关键字

2.3.1 实现单接口

需求:实现电脑使用Usb设备(鼠标、键盘)

  • IUsb接口:包含打开设备、关闭设备的功能
  • Mouse类:实现IUsb接口,并具备点击功能
  • KeyBoard类:实现IUsb接口,并具备输入功能
  • Computer类:包含开机功能、关机功能和使用IUsb设备功能
//IUsb接口
public interface IUsb {
    void openDevice();
    void closeDevice();
}
//Mouse类实现IUsb接口
public class Mouse implements IUsb {
    @Override
    public void openDevice() {
        System.out.println("Mouse open");
    }
    @Override
    public void closeDevice() {
        System.out.println("Mouse close");
    }
    public void click(){
        System.out.println("Mouse click");
    }
}
//KeyBoard类实现IUsb接口
public class KeyBoard implements IUsb {
    @Override
    public void openDevice() {
        System.out.println("KeyBoard open");
    }
    @Override
    public void closeDevice() {
        System.out.println("KeyBoard close");
    }
    public void input(){
        System.out.println("KeyBoard input");
    }
}
//电脑类,使用Use设备(鼠标、键盘)
public class Computer {
    public void open(){
        System.out.println("Computer open");
    }
    public void useUsb(IUsb iusb){
        iusb.openDevice();
        if (iusb instanceof KeyBoard){
            //向下转型
            KeyBoard keyBoard = (KeyBoard)iusb;
            keyBoard.input();
        }
        if (iusb instanceof Mouse){
            //向下转型
            Mouse mouse = (Mouse)iusb;
            mouse.click();
        }
        iusb.closeDevice();
    }
    public void close(){
        System.out.println("Computer close");
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.open();
        computer.useUsb(new Mouse());
        computer.useUsb(new KeyBoard());
        computer.close();
    }
}

运行结果:
Computer open
Mouse open
Mouse click
Mouse close
KeyBoard open
KeyBoard input
KeyBoard close
Computer close

2.3.2 实现多接口

public interface IRunning {
    void run();
}
public interface ISwimming {
    void swim();
}
public class Animal {
    public String name;
    public Animal(String name){
        this.name = name;
    }
}
//青蛙既能跑又能游
public class Frog extends Animal implements IRunning,ISwimming{
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + " is running");
    }
    @Override
    public void swim() {
        System.out.println(this.name + " is swimming");
    }
    public void act(){
        this.run();
        this.swim();
    }
}
public class Test {
    public static void main(String[] args) {
        Frog frog = new Frog("Frog");
        frog.act();
    }
}

运行结果:
Frog is running
Frog is swimming

2.4 接口的继承

在Java中,类和类之间是单继承的,⼀个类可以实现多个接口,接口与接口之间可以多继承

即:用接口可以达到多继承的目的

public interface IRunning {
    void run();
}
public interface ISwimming {
    void swim();
}
//Act接口继承IRunning和ISwimming接口
public interface Act extends IRunning,ISwimming{
    @Override
    void run();
    @Override
    void swim();
}
public class Animal {
    public String name;
    public Animal(String name){
        this.name = name;
    }
}
//青蛙既能跑又能游
public class Frog extends Animal implements Act{
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + " is running");
    }
    @Override
    public void swim() {
        System.out.println(this.name + " is swimming");
    }
    public void act(){
        this.run();
        this.swim();
    }
}
public class Test {
    public static void main(String[] args) {
        Frog frog = new Frog("Frog");
        frog.act();
    }
}

运行结果不变

2.5 default方法的作用

  • 默认实现:允许拥有具体的实现。实现类可以选择是否重写该方法
  • 多重继承的解决方法:当某个具体类实现了非常多的接口时,接口之间可能会存在同名的方法。通过default方法可以解决同名方法的冲突 ```java public interface IA {
    default void func(){
    System.out.println(“IA func”);
    } } public interface IB {
    default void func(){
    System.out.println(“IB func”);
    } } public class Demo implements IA,IB {
    @Override
    public void func() {
    //调用IA中的默认方法
    IB.super.func();
    } } public class Test {
    public static void main(String[] args) {
    Demo demo = new Demo();
    demo.func();
    } } ````在上述代码中必须在Demo类中重写func()方法才能解决同名冲突问题,所谓的重写就是选择调用IA还是IB中的default方法,并没有改变方法的原有实现。`如果IA和IB中是public
    abstract修饰的方法,没有具体实现,只能由Demo类来实现,那么必然有一个接口中的func()方法无法被重写
  • 向后兼容性:default方法使得在现有的接口中添加新方法成为可能,而不会破坏已有的实现类。如果没有default方法,添加新方法到接口会导致所有实现类都需要实现这个新方法,这会破坏向后兼容性

2.5 接口和抽象类的区别

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

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

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

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

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

相关文章

学习threejs,使用Physijs物理引擎

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…

allure生成测试报告(搭配Pytest、allure-pytest)

文章目录 前言allure简介allure安装软件下载安装配置环境变量安装成功验证 allure运行流程allure装饰器函数基本说明装饰器函数使用allure.attach 命令行运行利用allure-pytest生成中间结果json 查看测试报告总览页面每个tab页的说明类别页面测试套图表页面时间刻度功能页面包 …

龙虎榜——20250509

上证指数今天缩量,整体跌多涨少,走势处于日线短期的高位~ 深证指数今天缩量小级别震荡,大盘股表现更好~ 2025年5月9日龙虎榜行业方向分析 一、核心行业方向 军工航天 • 代表个股:航天南湖、天箭科技、襄阳轴承。 • 驱动逻辑…

操作系统的初步了解

目录 引言:什么是操作系统? 一、设计操作系统的目的 二、操作系统是做什么的: 操作系统主要有四大核心任务: 1. 管理硬件 2. 运行软件 3. 存储数据 4. 提供用户界面 如何理解操作系统的管理呢? 1. 什么是操作…

软件工程之软件项目管理深度解析

前文基础: 1.软件工程学概述:软件工程学概述-CSDN博客 2.软件过程深度解析:软件过程深度解析-CSDN博客 3.软件工程之需求分析涉及的图与工具:软件工程之需求分析涉及的图与工具-CSDN博客 4.软件工程之形式化说明技术深度解…

基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎

⭐️个人主页:小羊 ⭐️所属专栏:项目 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 项目背景技术栈和项目环境正排索引和倒排索引数据去标签与清洗下载数据源去标签 建立索引构建正排索引构建倒排索引 建立搜索引擎h…

Qt 通过控件按钮实现hello world + 命名规范(7)

文章目录 使用编辑框来完成 hello world通过编辑图形化界面方式通过纯代码方式 通过按钮的方式来创建 hello world通过编辑图形化界面方式通过纯代码方式 总结Qt Creator中的快捷键如何使用文档命名规范 简介:这篇文章着重点并不在于创建hello world程序&#xff0c…

关于大数据的基础知识(二)——国内大数据产业链分布结构

成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(二&a…

Winform(11.案例讲解1)

今天写两个案例,用于更好的理解控件的使用 在写之前先写一个类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _1.案例讲解 { internal class Student { public string …

电机密集型工厂环境下的无线通信技术选型与优化策略

点击下面图片带您领略全新的嵌入式学习路线 🔥爆款热榜 88万阅读 1.6万收藏 在电机、变频器、电焊机等强电磁干扰源遍布的工业环境中,无线通信系统的可靠性面临严峻挑战。本文从抗干扰能力、传输稳定性、实时性需求三大核心维度出发,结合工…

一文了解氨基酸的分类、代谢和应用

氨基酸(Amino acids)是在分子中含有氨基和羧基的一类化合物。氨基酸是生命的基石,人类所有的疾病与健康状况都与氨基酸有直接或间接的关系。氨基酸失衡可引起肝硬化、神经系统感染性疾病、糖尿病、免疫性疾病、心血管疾病、肾病、肿瘤等各类疾…

系统学习算法:动态规划(斐波那契+路径问题)

题目一: 思路: 作为动态规划的第一道题,这个题很有代表性且很简单,适合入门 先理解题意,很简单,就是斐波那契数列的加强版,从前两个数变为前三个数 算法原理: 这五步可以说是所有…

JAVA房屋租售管理系统房屋出租出售平台房屋销售房屋租赁房屋交易信息管理源码

一、源码描述 这是一套房屋租售管理源码,基于SpringBootVue框架,后端采用JAVA开发,源码功能完善,涵盖了房屋租赁、房屋销售、房屋交易等业务。 二、源码截图

掌握Multi-Agent实践(三):ReAct Agent集成Bing和Google搜索功能,采用推理与执行交替策略,增强处理复杂任务能力

一个普遍的现象是,大模型通常会根据给定的提示直接生成回复。对于一些简单的任务,大模型或许能够较好地应对。然而,当我们面对更加复杂的任务时,往往希望大模型能够表现得更加“智能”,具备适应多样场景和解决复杂问题的能力。为此,AgentScope 提供了内置的 ReAct 智能体…

Bearer Token的神秘面纱:深入解析HTTP认证头的设计哲学

为何有些Token会带Bearer? 在接口测试与开发中,我们经常会遇到这样的请求头: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... 这个神秘的"Bearer"前缀从何而来?为何不直接使用Authorization: Token..…

【国产化】在银河麒麟ARM环境下离线安装docker

1、前言 采用离线安装的方式。 关于离线安装的方式官网有介绍,但是说的很简单,网址:Binaries | Docker Docs 官网介绍的有几种主流linux系统的安装方式,但是没有kylin的,所以在此记录一下。 在安装过程中也遇到了些…

java volatile关键字

volatile 是 Java 中用于保证多线程环境下变量可见性和禁止指令重排序的关键字。 普通变量不加volatile修饰有可见性问题,即有线程修改该变量值,其他线程无法立即感知该变量值修改了。代码: private static int intVal 0; // 普通变量未加 …

Vibe Coding: 优点与缺点

如果你最近在开发圈子里,你很可能听说过这个新趋势"vibe coding"(氛围编程)。 我只能说我对此感受复杂。以下是原因。 优势 在构建新项目时,靠着氛围编程达到成功感觉很自由!但对于遗留代码来说情况就不同了,尽管也不是不可能。 实时反馈和快速迭代 Cursor(…

技术分享 | 如何在2k0300(LoongArch架构)处理器上跑通qt开发流程

近期迅为售后团队反馈,许多用户咨询:2K0300处理器采用了LA264处理器核,若要在该处理器上运行Qt程序,由于架构发生了变化,其使用方法是否仍与ARM平台保持一致? 单纯回答‘一致’或‘不一致’缺乏说服力&…

基于卷积神经网络和Pyqt5的猫狗识别小程序

任务描述 猫狗分类任务(Dogs vs Cats)是Kaggle平台在2013年举办的一个经典计算机视觉竞赛。官方给出的Kaggle Dogs vs Cats 数据集中包括由12500张猫咪图片和12500张狗狗图片组成的训练集,12500张未标记照片组成的测试集。选手需要在规定时间…