day19_抽象类丶接口

news2024/9/28 23:38:51

由来

当我们声明一个几何图形类:圆、矩形、三角形类等,发现这些类都有共同特征:求面积、求周长、获取图形详细信息。那么这些共同特征应该抽取到一个公共父类中。但是这些方法在父类中又无法给出具体的实现,而是应该交给子类各自具体实现。那么父类在声明这些方法时,就只有方法签名,没有方法体,我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类必须是抽象类

抽象类的语法格式

特点:没有方法体且被abstract修饰的方法

抽象方法的语法格式  

特点:抽象方法没有方法体 ,且被abstract关键字修饰

注意事项

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  2. 抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。

    理解:子类的构造方法中,有默认的super()或手动的super(实参列表),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

代码示例

定义抽象类

//抽象类
public abstract class Anima {
    //类中成员变量
    private String name;
    //抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。
    public Anima(String name) {
        this.name = name;
    }

    public Anima() {
    }
    //成员方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
    public abstract void eat();
}

 定义实现类

public class Dog extends Anima{

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

    public Dog() {
    }

    @Override
    //抽象类的子类,必须重写抽象父类中所有的抽象方法,除非该子类也是抽象类。 
    public void eat() {
        System.out.println("狗狗吃骨头");
    }
}

定义测试类

public class Test {
    public static void main(String[] args) {
        // Anima anima = new Anima();抽象类不能创建对象

        //只能创建其非抽象子类的对象。
        Dog dog = new Dog("大黄");
        dog.eat();//狗狗吃骨头
        System.out.println(dog.getName());//大黄
    }
}

接口

由来

电脑边上提供了USB插槽,这个插槽遵循了USB的规范,只要其他设备也是遵循USB规范的,那么就可以互联,并正常通信。至于这个电脑、以及其他设备是哪个厂家制造的,内部是如何实现的,我们都无需关心。

这种设计是将规范和实现分离,这也正是Java接口的好处。Java的软件系统会有很多模块组成,那么各个模块之间也应该采用这种面相接口的低耦合,为系统提供更好的可扩展性和可维护性。

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的is-a关系,而接口实现则是 "能不能"的has-a关系。理解:接口是从多个相似类中抽象出来的规范,不需要提供具体实现

  • 例如:你能不能用USB进行连接,或是否具备USB通信功能,就看你是否遵循USB接口规范
  • 例如:Java程序是否能够连接使用某种数据库产品,那么要看该数据库产品有没有实现Java设计的JDBC规范

为什么接口中只能声明公共的静态的常量?

  • 因为接口是标准规范,在规范中需要声明一些底线边界值,当实现者在实现这些规范时,不能去随意修改和触碰这些底线,否则就有“危险”。

接口的定义,它与定义类方式相似,但是使用 interface关键字。它也会被编译成.class文件,但一定要明确接口并不是类,而是另外一种引用数据类型。

接口中可以声明什么?

JDK8之前,接口中只允许出现:

  • 公共的静态的常量:其中public static final可以省略。
  • 公共的抽象的方法:其中public abstract可以省略
//定义接口
public interface Fly {
    //公共的静态的常量:其中public static final可以省略
    String name = "示例代码";

    // 公共的抽象的方法:其中public abstract可以省略
    void fly();
}

JDK1.8时,接口中允许声明默认方法和静态方法:

  • 公共的默认的方法:其中public 可以省略,建议保留,但是default不能省略。
    • 我们要在已有的老版接口中提供新方法时,如果添加抽象方法,就会涉及到原来使用这些接口的类就会有问题,那么为了保持与旧版本代码的兼容性,只能允许在接口中定义默认方法实现。比如:Java8中对Collection、List、Comparator等接口提供了丰富的默认方法。
    • 当我们接口的某个抽象方法,在很多实现类中的实现代码是一样的,此时将这个抽象方法设计为默认方法更为合适,那么实现类就可以选择重写,也可以选择不重写。
    • 重写时,default单词就不要再写了,它只用于在接口中表示默认方法,到类中就没有默认方法的概念了
  • 公共的静态的方法:其中public 可以省略,建议保留,但是static不能省略。之前的标准类库设计中,有很多Collection/Colletions或者Path/Paths这样成对的接口和类,后面的类中都是静态方法,而这些静态方法都是为前面的接口服务的,那么这样设计一对API,不如把静态方法直接定义到接口中使用和维护更方便
//定义接口
public interface Fly {
    //默认方法
    public default void start(){
        System.out.println("默认方法");
    }
    //静态方法
    public static void show(){
        System.out.println("静态方法");
    }
}

JDK1.9时,接口又增加了:

  • 私有方法:因为有了默认方法和静态方法这样具有具体实现的方法,那么就可能出现多个方法由共同的代码可以抽取,而这些共同的代码抽取出来的方法又只希望在接口内部使用,所以就增加了私有方法。

除此之外,接口中不能有其他成员,没有构造器,没有初始化块,因为接口中没有成员变量需要初始化。

接口的声明格式

实现接口

接口的使用,它不能创建对象,但是可以被实现(implements,类似于被继承)。类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也习惯称为接口的子类(严格来说,实现类不是子类)。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

注意:实现类不能继承接口中的静态方法和私有方法

实现接口语法格式

如何调用对应的方法

  • 对于接口的静态方法,直接使用“接口名.”进行调用即可。也只能使用“接口名."进行调用,不能通过实现类的对象进行调用

  • 对于接口的抽象方法、默认方法,只能通过实现类对象才可以调用。接口不能直接创建对象,只能创建实现类的对象

代码示例

定义接口

//定义接口
public interface LiveAble {
    // 定义抽象方法
    public abstract void eat();
    public abstract void breathe();
    //定义默认方法
    public default void sleep(){
        System.out.println("静止不动");
    }
    //定义静态方法
    public static void drink(){
        System.out.println("喝水");
    }
}

定义实现类Animal

public class Animal implements LiveAble{
    //重写/实现接口的抽象方法
    @Override
    public void eat() {
        System.out.println("吃东西");
    }

    //重写/实现接口的抽象方法
    @Override
    public void breathe(){
        System.out.println("吸入氧气呼出二氧化碳");
    }

    //重写接口的默认方法
    @Override
    public void sleep() {
        System.out.println("闭上眼睛睡觉");
    }
}

定义实现类Plant

public class Plant implements LiveAble {
    //重写/实现接口的抽象方法
    @Override
    public void eat() {
        System.out.println("吸收营养");
    }
    //重写/实现接口的抽象方法
    @Override
    public void breathe(){
        System.out.println("吸入二氧化碳呼出氧气");
    }
}

定义测试类

public class Test {
    public static void main(String[] args) {
        // 创建实现类(子类)对象
        Animal a = new Animal();
        // 调用实现后的方法
        a.eat(); //吃东西
        a.sleep(); //闭上眼睛睡觉
        a.breathe(); //吸入氧气呼出二氧化碳

        //创建实现类(子类)对象
        Plant p = new Plant();
        p.eat(); //吸收营养
        p.sleep(); //静止不动
        p.breathe(); //吸入二氧化碳呼出氧气

        //通过接口调用静态方法
        LiveAble.drink();
        // Animal.drink();错误,找不到符号
        // Plant.drink();错误,找不到符号
    }
}

接口的多实现

在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

实现格式:

注意事项:

  • 接口中,有多个抽象方法时,实现类如果不是抽象类就必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次
  • 当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法
  • 当一个类同时实现了多个接口,而多个接口中包含方法签名相同的默认方法时,要么选择保留其中一个,通过“接口名.super.方法名"的方法选择保留哪个接口的默认方法,要么选择自己完全重写

接口的多继承

一个接口能继承另一个或者多个接口接口的继承也使用 extends关键字,子接口继承父接口的方法。最底层的实现类(非抽象类)要实现接口里所有的抽象方法,包括接口继承下来的。

定义接口

package sgg1.demo06;
// 父接口
interface A {
    void a();
    public default void methodA(){
        System.out.println("A类默认方法");
    }
}
// 父接口
interface B {
    void b();
    public default void methodB(){
        System.out.println("B类默认方法");
    }
}
//子接口
interface C extends A,B{

}
//定义实现类
class D implements C{

    @Override
    public void a() { //重写a接口的抽象方法
        System.out.println("重写a接口的抽象方法");
    }


    @Override
    public void b() {//重写b接口的抽象方法
        System.out.println("重写b接口的抽象方法");
    }

}

定义测试类

public class Test {
    public static void main(String[] args) {
        D d = new D();
        d.a(); //重写a接口的抽象方法
        d.b(); //重写b接口的抽象方法
        d.methodA(); //A类默认方法
        d.methodA(); //A类默认方法
    }
}

  接口与实现类对象的多态引用

实现类实现接口,类似于子类继承父类,因此,接口类型的变量与实现类的对象之间,也可以构成多态引用。通过接口类型的变量调用方法,最终执行的是你new的实现类对象实现的方法体。

public class TestInterface {
    public static void main(String[] args) {
        Flyable b = new Bird();
        b.fly(); //展翅高飞

        Flyable k = new Kite();
        k.fly(); //别拽我,我要飞
    }
}
interface Flyable{
    //抽象方法
    void fly();
}
class Bird implements Flyable{

    @Override
    public void fly() {
        System.out.println("展翅高飞");
    }

}
class Kite implements Flyable{

    @Override
    public void fly() {
        System.out.println("别拽我,我要飞");
    }

}

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

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

相关文章

当遇到国外客户的问题,你解决不了的时候怎么办

对我来说,今年的这个春节假期有点长,差不多休了一个月。复工之后,截止目前做到了60万RMB的业绩,但是相较于往年,整体状态还是差了些。往年的春节,我都是随时待命的状态,整个春节天天坐于电脑前&…

JSP 和 JSTL

文章目录🍓摘要🍓一、JSP🍉1.1 JSP的基础语法🍫1.1.1 简介🍫1.1.2 依赖🍫1.1.3 注释🍫1.1.4 Scriptlet 脚本🍉1.2 JSP的指令标签🍫1.2.1 include 静态包含🍫1…

2023年数学建模美赛A题(A drought stricken plant communities)分析与编程

2023年数学建模美赛A题(A drought stricken plant communities)分析与编程 2023年数学建模美赛D题(Prioritizing the UN Sustainability Goals)分析与编程 特别提示: 1 本文介绍2023年美赛题目,进行深入分析…

台式计算机加固态硬盘,台式机添加固态硬盘教程_台式主机固态硬盘怎么安装-win7之家...

固态硬盘是用固态电子存储芯片阵列制成的硬盘,也是电脑中比较常见的内存硬件,有些用户在使用电脑时候,由于内存不足导致系统运行较卡的情况,往往会选择添加固态硬盘来解决,那么台式主机固态硬盘怎么安装呢?…

Ansible中的角色使用(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径:配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…

2023.2.17-博客记录

1.斐波那契数列的复杂度 参考于:斐波那契数列时间复杂度 运用到了递归思想 那么,推导:时间复杂度 f(n) f(n-1) f(n-2) 每一层都包含一个加法操作 例如n 8时,T(n) 2^0 2^1 2^2 2^3 2^4 2^5 2^6 2^7-1 O(n) 2^7-1 2…

四六级真题长难句分析与应用

一、基本结构的长难句 基本结构的长难句主要考点:断开和简化 什么是长难句? 其实就是多件事连在了一块,这时候句子就变长、变难了 分析步骤: 第一件事就是要把长难句给断开,把多件事断开成一件一件的事情&#xff0…

ElementUI`resetFields()`方法避坑

使用ElementUI中的resetFields()方法有哪些注意点 场景一 场景一:当编辑弹出框和新增弹出框共用时,编辑数据后关闭编辑弹出框时调用this.$refs.form.resetFields()无法清空弹出框 问题代码: // 点击新增按钮handleAdd() {this.dialogVi…

《Qt6开发及实例》6-3 双缓冲机制

目录 一、原理与设计 1.1 原理 1.2 设计 二、绘图区的实现 2.1 鼠标移动事件 2.2 重绘函数&调整大小函数&清除屏幕 三、主窗口的实现 3.1 代码 一、原理与设计 1.1 原理 双缓冲就是在绘制控件时,将内容绘制在一个图片中,再将图片一次性…

全局状态管理插件 Vuex 介绍及使用

文章目录Vuex 是什么简介Vuex 如何存储数据Vuex 核心概念单向数据流StateGetterMutationActionModuleVuex 使用实例总结Vuex 是什么 简介 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以…

Linux环境下(CentOS 7)安装Java(JDK8)

Linux环境下(CentOS 7)安装Java(JDK8) 一、安装教程 1.1 首先,进入oracle官网下载jdk8的安装包,下载地址如下,这里以 jdk-8u121-linux-x64.tar.gz安装包为例。 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21…

2023美赛(MCM/ICM)数据汇总

2023美赛已经开始了十二个小时了,对于本次比赛,赛题 难度都不大。主要就是收集数据的问题 ,为了更好地帮助大家选题,我们将 我们今天已经收集到的数据进行汇总,分享。其中,首先是A、E题目都提及的天气数据&…

C语言学习_DAY_4_判断语句if_else和分支语句switch_case【C语言学习笔记】

高质量博主,点个关注不迷路🌸🌸🌸! 目录 1.案例引入 2.if判断语句的语法与注意事项 3.switch多分支语句的语法与注意事项 前言: 书接上回,我们已经学习了所有的数据类型、运算符,并且可以书写…

基于matlab/simulink的风光柴储微电网仿真建模

模型是基于之前的风光储系统上增加一部分柴油发电机系统,后面文章我会单独介绍柴油机这一部分,主要应用在船舶电力系统,一般小型电网黑启动也会用到。 风光柴储微电网发电系统是一种小型发电系统,同时具备并网运行和孤岛运行的功能…

气敏电阻的原理,结构,分类及应用场景总结

🏡《总目录》 目录 1,概述2,结构3,工作原理4,分类4.1,加热方式分类4.2,材料分类4.3,氧化还原分类5,应用场景6,总结1,概述 气敏电阻是指电阻值随着环境中某种气体的浓度变化而变化的电阻,本文对其工作原理,结构,分类和应用场景进行总结。 2,结构 气敏电阻由防爆…

Leetcode(每日一题)——1237. 找出给定方程的正整数解

摘要 1237. 找出给定方程的正整数解 一、暴力求解 根据题目给出的x和y的取值范围,枚举所有的 x,y数对,保存满足f(x,y)z的数对,最后返回结果。 /*** description 使用的暴力法 直接遍历符合的就添加到结果中* param: customfunction* param…

能不能做好性能测试,要看你有没有性能测试思维

获取性能需求 01、用户数信息 1、调查系统当前和未来使用的用户数 系统用户数 本系统目前注册的用户数,注册用户数并不代表他会每天并且无时无刻的使用着。 在线用户数 同时在线对系统进行操作的用户数量(相当于混合场景) 并发用户数 …

第9天-商品服务(电商核心概念,属性分组开发及分类和品牌的级联更新)

1.电商核心概念 1.1.SPU与SKU SPU:Standard Product Unit(标准化产品单元) 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个 产品的特性。 决定商品属性的值 SKU:Stock…

第43天| 123.买卖股票的最佳时机III、 188.买卖股票的最佳时机IV

1.题目链接:123. 买卖股票的最佳时机 III 题目描述: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意:你不能同时参与多笔交易&#…

基于深度神经网络的3D模型合成【Transformer vs. CNN】

本文介绍用于3D模型合成的transformer网络与深度卷积网络。 推荐:使用 NSDT场景设计器 快速搭建 3D场景。 1、概述 从单一视角合成 3D 数据是一种基本的人类视觉功能,这对计算机视觉算法来说极具挑战性,这是一个共识。 但在 3D 传感器&#…