【剧前爆米花--爪哇岛寻宝】抽象类和接口(上)——理论及逻辑理解

news2025/2/21 20:20:32

作者:困了电视剧

专栏:《JavaSE语法与底层详解》

文章分布:这是一篇关于抽象类和接口的文章,在本篇文章中我会介绍其相关的定义和语法,并且揭示接口和抽象类的运行逻辑,提高对面对象编程的理解。

 

目录

抽象类

抽象类概念及其语法

抽象类特性

抽象类作用

接口 

接口的概念和语法

接口的特性

接口和上转型在项目中被使用的逻辑(核心)

类,抽象类,接口的比较


抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的, 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
举个栗子:我现在有个动物类,动物都有一个行为那就是发出叫声,我可以定义一个Cat类继承这个动物类,然后Cat类在通过多态实现不同的行为——喵喵叫,此时如果我将动物类定义为一个普通类,那动物类就有一个叫声的行为,但是由于每个动物的叫声都不一样,那么此时这个动物类的叫声就发生了逻辑上的错误,即我不知道它是什么动物,无法判断它的叫声。
而如果我们把这个动物类设计成一个抽象类,那么我们就可以将这个叫声的方法设置成抽象方法,从而实现逻辑上的自洽,并且利用编译器的语法纠错提高程序的安全性。

抽象类概念及其语法

Java 中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用 给出具体的实现体。
注意: 抽象类也是类,内部可以包含普通方法和属性,甚至构造方法。
abstract class Animal{
    int age;
    String name;
    String sex;
    //构造方法
    public Animal(int age, String name, String sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }
    public Animal(){}
    //抽象方法
    public abstract void eat();
    public abstract void speak();
    //普通方法
    public void sleep(){}
}

抽象类特性

1. 抽象类不能直接实例化对象
2. 抽象方法不能是 private
3. 抽象方法不能被 final static 修饰,因为抽象方法要被子类重写
4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必      须要使用 abstract 修饰
5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
解释:1.这一点是设计抽象类提高代码安全性的核心特性,就像我前文说的那样,有的时候一个类并不能表现一个特定的行为,但是当我们将它定义成普通类时,它就可以进行实例化,从而进行相应的行为,这在逻辑上并不自洽。
当我们用抽象类对其进行定义的时候,由于其不能进行实例化,所以就不会表现出相应的行为,减少了出错的可能,提高了代码的安全性。
2.重写是子类对父类的允许访问的方法的实现过程进行重新编写,用private修饰不论是不是抽象方法都不能进行重写。
abstract class Animal{
    int age;
    String name;
    String sex;
    //构造方法
    public Animal(int age, String name, String sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }
    public Animal(){}
    //抽象方法
    public abstract void eat();
    public abstract void speak();
    //普通方法
    private void sleep(){}
}

class Cat extends Animal{
    @Override
    public void eat() {

    }

    @Override
    public void speak() {

    }
    @Override
    public void sleep(){
        System.out.println("aaaaaa");
    }
}

这段代码会报错

4.由于抽象类并不能实例化对象,所以如果抽象类想要被使用的话就必须被继承,被继承到子类时也是抽象方法,所以如果子类不对其进行重写,则子类包含抽象方法,只能用抽象类来进行定义。

抽象类作用

使用抽象类的场景就如上面的代码 , 实际工作不应该由父类完成 , 而应由子类完成 . 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的 . 但是父类是抽象类就会在实例化的时候提示错误 , 让我们尽早发现问题。
很多语法存在的意义都是为了 " 预防出错 ", 例如我们曾经用过的 final 也是类似 . 创建的变量用户不去修改 , 不就相当于常量嘛? 但是加上 fifinal 能够在不小心误修改的时候 , 让编译器及时提醒我们。

接口 

接口的概念和语法

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用 。在Java 中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
接口的定义格式与定义类的格式基本相同,将 class 关键字换成 interface 关键字,就定义了一个接口。
Java 中,类和类之间是单继承的,一个类只能有一个父类,即 J ava中不支持多继承 ,但是 一个类可以实现多个接口
注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类
Java 中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到 多继承的目的。
接口可以继承一个接口 , 达到复用的效果 . 使用 extends 关键字
public interface Code {
    public abstract void test1();
    public abstract void test2();
}

interface Code_test1 extends Code{
    public abstract void test3();
}

interface Code_test2 extends Code,Code_test1{
    public abstract void test4();
}
class Test1 implements Code,Code_test1,Code_test2{
    @Override
    public void test1() {
        
    }

    @Override
    public void test2() {

    }

    @Override
    public void test3() {

    }

    @Override
    public void test4() {

    }
}

接口的特性

1. 接口类型是一种引用类型,但是不能直接 new 接口的对象
2.  接口中每一个方法都是 public 的抽象方法 , 即接口中的方法会被隐式的指定为 public   abstract (只能是public abstract,其他修饰符都会报错 )
3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
4. 重写接口中方法时,不能使用默认的访问权限
5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static fifinal 变量
6. 接口中不能有静态代码块和构造方法
7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是 .class
8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
9. jdk8 中:接口中还可以包含 default 方法。

解释:

1.原因与抽象类类似,都是旨在提高代码的安全性,并且保证逻辑上的自洽。

2. 第二点和第五点中方法和变量前面的修饰符可加可不加,也可不加完,但在实际的项目中为了保证代码的简洁和统一,一般什么都不加。

public interface Code {
    int a=0;
    final int b=0;
    public final int c=0;
    public abstract void test1();
    public void test2();
}

interface Code_test1 extends Code{
    abstract void test3();
}

interface Code_test2 extends Code,Code_test1{
    void test4();
}
class Test1 implements Code,Code_test1,Code_test2{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }

    @Override
    public void test3() {

    }

    @Override
    public void test4() {

    }
}

 3.第四点中不能使用默认的类型是因为重写要求重写后的方法的访问权限不能低于重写前的方法,而在接口中默认的访问权限是public。

4.第七点编译后如图:

 可以看到后缀名也是.class。

接口和上转型在项目中被使用的逻辑(核心)

 接口的命名一般采用形容词性的单词。

我们来看一段代码:

public class Javabit_Code {
    public static void main(String[] args) {
        Animal cat=new Cat();
        Animal bird=new Bird();
        Action ac=new Action();
        ac.eat(cat);
        ac.eat(bird);
        ac.speak(cat);
        ac.speak(bird);
        ac.fly(new Bird());
    }
}

class Action{
    public void eat(Animal animal){
        animal.eat();
    }
    public void speak(Animal animal){
        animal.speak();
    }
    public void fly(Iflying animal){
        animal.fly();
    }
}

interface Iflying{
    void fly();
}

abstract class Animal{
    int age;
    String name;
    String sex;
    //构造方法
    public Animal(int age, String name, String sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }
    public Animal(){}
    //抽象方法
    public abstract void eat();
    public abstract void speak();
    //普通方法
    public void sleep(){}
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃猫粮");
    }

    @Override
    public void speak() {
        System.out.println("喵喵叫");
    }
}

class Bird extends Animal implements Iflying{
    @Override
    public void eat() {
        System.out.println("吃鸟粮");

    }

    @Override
    public void speak() {
        System.out.println("叽叽喳喳");

    }

    @Override
    public void fly(){
        System.out.println("鸟在飞");
    }
}

在Action这个类中,我需要完成一些行为 ,但是此时由于我又不知道具体哪一个动物会被当做参数传进来,所以这里展现了多态的思想。

对于上转型来说,它提供了一种兼容,在Action类中的eat方法中,我需要传一个Animal的参数,这时我就可以运用上转型来完成这一点。

对于接口来说,它也提供了一种兼容,但和上转型又有点区别,上转型是“猫是动物”的关系即“is-a”的关系,而接口更像是“have-a”的关系,在本例中,他是只要实现了Iflying接口的类,其所实例化的对象就能当成参数,换个角度想,实现了Iflying接口就说明这个类实例化的对象会飞,而Action中的fly方法则是,只要是会飞的都可以实现这个方法。所以接口一般也用形容词进行命名。

这就是其中的逻辑关系。

类,抽象类,接口的比较

类就相当于一张盖楼用的图纸,我用这张图纸可以实例化一个楼。

抽象类就相当于没画完的图纸,这张图纸在某些地方,比如这栋楼的厕所建造时需要的信息没有画,只画了这个厕所要建在大致哪个位置,所以由于信息不全不能实例化一个楼。

接口,就相当于一套楼房大致框架的信息,你需要先把这些信息抄到一张图纸上,然后再在这张图纸上按照实际的需求进行补全,这样才能实例化一个大楼。

以上就是本篇文章的全部内容,如果对你有帮助还请三连,如有疏漏欢迎指正。

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

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

相关文章

吴恩达week6 ~批量梯度下降 指数加权平均 动量梯度下降 学习率衰减 Adam

文章目录前言一、小批量梯度下降 mini-batch1、batch gradient descent2、stochastic gradient descent3、mini-batch gradient descent二、指数加权平均1.什么是指数加权平均2、理解指数加权平均3、与普通求平均值的区别4、指数加权平均的偏差修正三、gradient descent with m…

Allegro批量替换过孔类型操作指导

Allegro批量替换过孔类型操作指导 Allegro支持批量替换过孔类型,具体操作如下 例如需要把这些VIA10的过孔全部替换成VIA8的过孔 选择菜单上面的Tool-padstack-Group edit 右击选择temp Group 选中需要替换的过孔 选完之后右击选择complete 弹出Padstack Map窗口,modify…

java中多线程、并发、并行、线程与进程、线程调度、创建线程的方式

多线程: 多线程比单线程快,前面简单介绍过:集合如果是不安全的,那么它就是多线程的,了解多线程之前,先了解什么是并发和并行。 并发:指两个或多个事件在同一个时间段内发生。 并行&#xff1…

高通平台开发系列讲解(AtCoP篇)AtCoP架构简介

文章目录 一、ATCoP简介二、ATCoP架构三、流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇讲介绍高通ATCoP的架构。 一、ATCoP简介 ATCoP(AT Command Processor)是高通平台对于AT命令处理的模块,通过它,我们可以实现对AT命令的修改和新增。ATCoP接收从串口…

[附源码]Python计算机毕业设计公司办公自动化系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

跟大佬展开激励讨论String的不可变性

目录 大佬证明: 我的证明: 后续 什么是不可变? String为什么不可变 为什么要设计成为不可变的呢? 1.首先我们最先可以想到的Java主要做的就是安全 2.其次是字符串常量池的需要 String真的不可变吗? ps&#…

平淡无奇,2022年终总结

1前言 一年又一年,时间过得太快啦! 最近总是想着2022年的点点滴滴,一年时光不得写点什么不一样的,可是思前想后觉得这一年也没什么不一样的啊。所以呢,2022年终总结标题就取名为平淡无奇。 人一生最重要的是什么&#…

Java Servlet + H2数据库之集成环境配置

在 EclipseMavenTomcat 集成开发环境配置 搭建了一个Servlet的开发环境,整合Tomcat 作为Web容器。如何要加入数据库开发要怎么处理呢? 在实际开发中,一般会选择MySQL,Oracle 等数据库, 但是如果只是学习和演示&#x…

DPDK源码分析之网络基础知识

字节对齐 attribute ((aligned (1))); 在设计不同CPU下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样. 如果跨越了4字节边界存储&#xff…

java之JVM的位置和体系结构

JVM的概念: JVM 即 Java Virtual Machine,中文名为 Java虚拟机,一般情况下,对于C/C 程序,编译成二进制文件后,就可以直接执行了,但Java 需要使用 javac 编译成 .class 文件,还需要使…

【LSTM回归预测】基于matlab主成分分析结合BiLSTM数据回归预测【含Matlab源码 2276期】

一、LSTM和BiLSTM神经网络结构及原理介绍 长短期记忆网络(Long short-term memory, LSTM)实质上可以理解为一种特殊的RNN,主要是为了解决RNN网络在长序列训练过程中发生梯度消失和梯度爆炸的问题。相比于RNN,LSTM主要是引入了细胞形态(cell state)用于保存长期状态&#xff0c…

世界杯决赛倒计时,你最看好谁

一、期待终极决赛 C站肯定有许多看球的朋友吧。明天即将迎来2022年世界杯终极对决,阿根廷队对战法国。来赶个晚集,也来聊聊世界杯,下一个四年就是2026,会不会还有这种精神呢。先来回顾一下本轮世界杯比赛中的对阵吧。 本轮世界杯中…

Win11+RTX3060+Anconda+CUDA11.3+cuDNN8.2+Pytorch1.10一条龙服务2

Win11RTX3060AncondaCUDA11.3cuDNN8.2Pytorch1.10一条龙服务 (1)查看安装了哪些包 conda list(2)查看当前存在哪些虚拟环境 conda env list (3)创建虚拟环境,你可以创建好几个虚拟环境,虚拟环…

Flex布局小练--博文列表item布局实现

文章目录前言元素组成实现html部分布局总结前言 今天划一个水先,没办法,作孽没写完,什么这不是作孽的一部分嘛?!听不见,听不见。 来先看一下我们要做的一个效果: 首先是这个页面下面的&#xf…

如何基于Jetbrains IDEA DataBase从数据库表中生成对应的Java Bean

在日常的项目开发过程中,大部分人可能都会遇到过想从表自动生成带有注释的Java Bean,在Jetbrains IDEA中通过DataBase工具也是可以生成的。Jetbrains IDEA的Database借助一个名称为Generate POJOs.groovy的groovy模板文件,可以帮我们做代码生…

Python工程师Java之路(t)SpringBoot部署步骤 java -jar

文章目录步骤1、开发环境2、新建工程3、新建controller4、开发环境试运行和测试5、打包运行命令补充步骤 1、开发环境 WIN10IDEA2021Maven3.6.3JDK1.8 2、新建工程 选择Spring和Java版本 添加依赖 3、新建controller package com.example.demo.controller;import org.spr…

macOS Ventura 13.1 (22C65) Boot ISO 原版可引导镜像

本站下载的 macOS Ventura 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装。 2022 年 12 月 13 日,macOS Ventura 13.1 推出了“无边记”&#x…

基于python的PatchMatchStereo立体匹配算法实现

文章目录前言一、PatchMatchStereo是什么?1.随机初始化2.迭代传播2.1空间传播2.2视图传播2.3帧间传播2.4平面细化二、PatchMatchStereo立体匹配算法实现前言 PatchMatchStereo是Michael Bleyer等在2011年发表于British Machine Vision Conference(BMVC&a…

机器学习 鸢尾花数据集划分 训练集和测试集

目录 一:加载数据 二:数据集整理 三:数据集划分 一:加载数据 加载数据,并创建一个DataFrame,便于数据分析 from sklearn.datasets import load_iris import pandas as pd import numpy as np from skle…

大数据:计算学生成绩

文章目录一、提出任务二、任务进行(一)准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录(二)实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建成绩映射器类5、创建成绩驱动器类6、启动成绩驱动器类…