Java面向对象编程实战详解(图书管理系统示例)
文章目录
- 面向编程概念
- 图书管理系统示例
- 需求分析
- 设计阶段
- 编码实现
- 创建目录结构
- Book类的编码
- BookList类的编码
- User类的编码
- AdminUser类的编码
- NormalUser类的编码
- 启动类的编写
- 具体的操作实现
- IOperation接口
- 新增图书的实现
- 借阅图书的实现
- 删除图书的实现
- 显示图书的实现
- 查找图书的实现
- 归还图书的实现
- 退出系统操作
- 测试阶段
- 管理员用户功能测试
- 查找图书操作
- 新增图书操作
- 展示图书操作
- 删除图书操作
- 普通用户功能测试
- 查找图书操作
- 借阅图书操作
- 归还图书操作
- 面向对象编程思想的体现
- 类的定义和对象的创建
- 封装
- 继承
- 多态
- 抽象类
- 接口
- 总结
面向编程概念
Java面向对象编程(Object-Oriented Programming,OOP)是Java语言的核心特性之一,它提供了一种组织代码的方法,将现实世界中的事物抽象为对象,并通过对象之间的交互来构建程序。Java面向对象编程包含以下主要概念:
-
类和对象(Class and Object):
类是面向对象编程的基本构建块,它是对一组具有相同属性和行为的对象的抽象描述。对象是类的实例化结果,它是内存中的实体,具有类所定义的属性和行为。类定义了对象的结构和行为,而对象则代表了真实世界中的具体实体。 -
封装(Encapsulation):
封装是一种将数据和行为封装在类中,阻止外部直接访问和修改对象的内部状态的特性。通过封装,类可以隐藏其实现细节,并通过公共的方法提供对内部状态的访问和操作。这有助于提高代码的可维护性和安全性。 -
继承(Inheritance):
继承是一种类之间的关系,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和行为。子类可以复用父类的代码,并且可以在不修改父类的情况下增加新的功能。继承提供了代码重用和层次化组织的能力。 -
多态(Polymorphism):
多态是指同一操作可以在不同的对象上产生不同的结果。它允许我们使用统一的接口来处理不同类的对象,从而提高代码的灵活性和可扩展性。多态有两种形式:静态多态(方法重载)和动态多态(方法重写,也称为覆盖)。 -
抽象类(Abstract Class):
抽象类是不能被实例化的类,它用于作为其他类的基类,提供一种对类的抽象描述。抽象类可以包含抽象方法和具体方法,子类必须实现抽象方法才能被实例化。抽象类常常用来定义类的通用行为和属性。 -
接口(Interface):
接口是一种特殊的抽象类,它定义了一组抽象方法,但不包含具体的实现。类可以实现(implements)一个或多个接口,实现接口的类必须提供接口中定义的所有方法。接口提供了一种多继承的机制,使得类可以在不同的继承树上实现不同的功能。
图书管理系统示例
需求分析
-
确定系统的功能:明确图书管理系统的基本功能,如查找图书、新增图书、删除图书、显示图书、借阅图书、归还图书等功能。
-
定义用户角色和权限:确定系统中的用户角色,如读者、管理员等,并定义他们的权限和操作范围。
- 普通用户:查找图书、借阅图书、归还图书
- 管理员:查找图书、新增图书、删除图书、显示图书
-
识别数据需求:分析需要存储的数据,如图书信息、读者信息、借阅记录等,并确定数据之间的关系。
- 图书名字、作者、价格、图书类型、图书是否借出
- 管理员、用户名字
设计阶段
- 架构设计:设计系统的整体架构,包括图书类、图书馆类、读者类等的设计,以及它们之间的关系。
- 接口设计:进行操作的接口。
- 数据库设计:咱们这就是一个JavaSe的小项目,暂时不涉及数据库(使用数组存储,不是持久化存储)。
编码实现
创建目录结构
根据需求分析,我们的图书管理系统有图书、用户、然后还有用户对图书的操作。所以我们先把这三个包创建好。
- book这个包里放跟图书有关的,是Book类和存储图书的BookList类,
- operation包放的是所有的操作类,
- user包放的是和用户有关的类。
值得注意的是,我们可以定义一个IOperation接口,让所有的操作继承这个接口,之后只要是进行操作就只要调用这个接口就好了。另外我们的User类,实际上是一个抽象的概念,实际上我们是普通用户和管理员是实际的,所以我们可以定义一个抽象的User类,然后派生出具体的用户。最后,我们我们还要创建一个启动类,作为整个程序的入口。
Book类的编码
package book;/*** @Author: Fourteen-Y* @Description: 图书信息,包括书名、作者、价格、类型、是否被借出* @Date: 2023/7/27 12:04*/
public class Book {// 图书的属性private String name;private String author;private int price;private String type;private boolean isBorrowed;// 图书的构造方法,实例对象的时候能直接定义图书对象public Book(String name, String author, int price, String type) {this.name = name;this.author = author;this.price = price;this.type = type;}// getter和setter方法,图书的属性被声明为私有,提供公共的方法来让外部代码访问这些属性的值。public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}// 重写toString方法,更好的打印图书信息@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +", type='" + type + '\'' +// 三目运算符 当isBorrowed为true时,输出已借出,否则输出未借出((isBorrowed == true) ? " ,已借出" : " ,未借出")+// ", isBorrowed=" + isBorrowed +'}';}
}
BookList类的编码
package book;/*** @Author: Fourteen-Y* @Description: 对图书的存储* @Date: 2023/7/27 12:04*/
public class BookList {/*** 创建一个数组,用来存放书籍,一开始默认5本书*/private static Book[] books = new Book[5];/*** 数组中放了书的个数*/private int usedSize;/*** 默认存放的书籍*/public BookList() {books[0] = new Book("三国演义","罗贯中",34,"小说");books[1] = new Book("西游记","吴承恩",24,"小说");books[2] = new Book("红楼梦","曹雪芹",30,"小说");books[3] = new Book("水浒传","施耐庵",34,"小说");books[4] = new Book("西厢记","王实甫",34,"小说");this.usedSize = 5;}public int getUsedSize() {return usedSize;}public void setUsedSize(int usedSize) {this.usedSize = usedSize;}//借书还书的操作,涉及到数组的操作/*** 获取pos下标的书* @param pos* @return*/public Book getPos(int pos) {return books[pos];}/*** 给数组的pos位置,放一本书* @param pos* @param book*/public static void setBooks(int pos, Book book) {books[pos] = book;}
}
User类的编码
package user;import book.BookList;
import operation.IOperation;/*** @Author: Fourteen-Y* @Description: 用户抽象类 有两个子类:普通用户和管理员* @Date: 2023/7/27 12:10*/
public abstract class User {protected String name;/*** 把所有的操作都放到这个数组中 通过下标来选择具体的操作*/public IOperation[] ioPerations;public User(String name) {this.name = name;}public abstract int menu();/*** 根据用户输入的选项,调用对应的操作* @param choice 用户输入的选项* @param bookList 图书列表*/public void doOperation(int choice, BookList bookList) {// work是所有操作的具体实现,传入要操作的书籍数组ioPerations[choice].work(bookList);}
}
AdminUser类的编码
package user;import operation.*;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description: 管理员 1.查找图书 2.新增图书 3.删除图书 4.显示图书 0.退出系统* @Date: 2023/7/27 12:09*/
public class AdminUser extends User {public AdminUser(String name) {super(name);// 把所有的操作在数组中new出来,// 由于还没实现这些具体的操作,所以一下代码展示会报错this.ioPerations = new IOperation[] {new ExitOperation(),new FindOperation(),new AddOperation(),new DelOperation(),new DisplayOperation(),};}/*** 管理员菜单 1.查找图书 2.新增图书 3.删除图书 4.显示图书 0.退出系统* @return 返回用户输入的选项,供主程序调用*/@Overridepublic int menu() {System.out.println("欢迎管理员"+this.name+"登录");System.out.println("1.查找图书");System.out.println("2.新增图书");System.out.println("3.删除图书");System.out.println("4.显示图书");System.out.println("0.退出系统");Scanner sc = new Scanner(System.in);int choice = sc.nextInt();return choice;}
}
NormalUser类的编码
package user;import operation.*;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description: 普通用户 有四个操作:查找图书 借阅图书 归还图书 退出系统* @Date: 2023/7/27 12:10*/
public class NormalUser extends User{public NormalUser(String name) {super(name);this.ioPerations = new IOperation[] {new ExitOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation(),};}/*** 普通用户菜单 1.查找图书 2.借阅图书 3.归还图书 0.退出系统* @return 返回用户输入的选项,供主程序调用*/@Overridepublic int menu() {System.out.println("欢迎"+this.name+"登录");System.out.println("1.查找图书");System.out.println("2.借阅图书");System.out.println("3.归还图书");System.out.println("0.退出系统");Scanner sc = new Scanner(System.in);int choice = sc.nextInt();return choice;}
}
启动类的编写
import book.BookList;
import user.AdminUser;
import user.NormalUser;
import user.User;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description:* @Date: 2023/7/27 12:11*/
public class Main {public static User login(){System.out.println("请输入你的姓名:");Scanner sc = new Scanner(System.in);String name = sc.next();System.out.println("请输入你的身份:1.管理员 2.普通用户");int choice = sc.nextInt();if(choice == 1) {return new AdminUser(name);}else {return new NormalUser(name);}}public static void main(String[] args) {BookList bookList = new BookList();User user = login();while(true) {int choice = user.menu();user.doOperation(choice,bookList);}}
}
具体的操作实现
IOperation接口
package operation;import book.BookList;/*** @Author: Fourteen-Y* @Description: 新增图书* @Date: 2023/7/27 12:09*/
public interface IOperation {// 由于接口中的方法都是抽象方法,所以可以省略public abstractvoid work(BookList bookList);
}
新增图书的实现
package operation;import book.Book;
import book.BookList;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description:* @Date: 2023/7/27 12:07*/
public class AddOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("新增图书!");System.out.println("请输入图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();System.out.println("请输入图书的作者");String author = sc.nextLine();System.out.println("请输入图书的类型");String type = sc.nextLine();System.out.println("请输入图书的价格");int price = sc.nextInt();// 创建一个Book对象Book book = new Book(name,author,price,type);// 当BookList满了的时候,自动扩容成原来的2倍BookList.ensureCapacity(bookList);int currentSize = bookList.getUsedSize();BookList.setBooks(currentSize,book);// 更新usedSizebookList.setUsedSize(currentSize + 1);System.out.println("新增成功!");}
}
上面用了一个确保容量的函数,自动扩容的函数,我们在BookList类里面加上这个函数
public static void ensureCapacity(BookList bookList) {// 如果当前数组已经满了,就扩容成原来的2倍if (bookList.getUsedSize() == books.length) {Book[] newBooks = new Book[2 * books.length];for (int i = 0; i < books.length; i++) {newBooks[i] = books[i];}books = newBooks;} }
借阅图书的实现
package operation;import book.Book;
import book.BookList;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description:* @Date: 2023/7/27 12:08*/
public class BorrowOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("借阅图书!");System.out.println("请输入你要借阅图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();// 1.查找书籍是否存在int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getPos(i);if (book.getName().equals(name)) {// 2.判断书籍是否被借出if (book.isBorrowed()) {System.out.println("这本书已经被借出去了!");return;}// 3.借阅书籍book.setBorrowed(true);System.out.println("借阅成功!");return;}}System.out.println("没有你要借阅的图书");}
}
删除图书的实现
package operation;import book.Book;
import book.BookList;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description: 删除图书* @Date: 2023/7/27 12:08*/
public class DelOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("删除图书!");System.out.println("请输入你要删除图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();// 1.查找书籍是否存在int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getPos(i);if (book.getName().equals(name)) {// 2.删除书籍for (int j = i; j < currentSize - 1; j++) {Book book1 = bookList.getPos(j + 1);BookList.setBooks(j,book1);}bookList.setUsedSize(currentSize - 1);System.out.println("删除成功!");return;}}System.out.println("没有你要删除的书!");}
}
显示图书的实现
package operation;import book.Book;
import book.BookList;/*** @Author: Fourteen-Y* @Description: 展示图书* @Date: 2023/7/27 12:08*/
public class DisplayOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("展示图书!");int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {Book book = bookList.getPos(i);System.out.println(book);}}
}
查找图书的实现
package operation;import book.BookList;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description: 查找图书* @Date: 2023/7/27 12:09*/
public class FindOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("查找图书!");System.out.println("请输入你要查找图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {if (bookList.getPos(i).getName().equals(name)) {System.out.println("找到这本书了,信息如下");System.out.println(bookList.getPos(i));return;}}System.out.println("没有这本书!");}}
归还图书的实现
package operation;import book.BookList;import java.util.Scanner;/*** @Author: Fourteen-Y* @Description: 归还图书* @Date: 2023/7/27 12:09*/
public class ReturnOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("归还图书!");System.out.println("请输入你要归还图书的名字:");Scanner sc = new Scanner(System.in);String name = sc.nextLine();int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {if (bookList.getPos(i).getName().equals(name)) {if (bookList.getPos(i).isBorrowed()) {bookList.getPos(i).setBorrowed(false);System.out.println("归还成功!");return;}System.out.println("这本书没有被借出去!");return;}}System.out.println("这本书不是该图书馆的书!");}
}
退出系统操作
package operation;import book.BookList;/*** @Author: Fourteen-Y* @Description: 退出系统* @Date: 2023/7/27 12:08*/
public class ExitOperation implements IOperation{@Overridepublic void work(BookList bookList) {System.out.println("退出系统!");int currentSize = bookList.getUsedSize();for (int i = 0; i < currentSize; i++) {BookList.setBooks(i,null);}System.exit(0);}
}
测试阶段
管理员用户功能测试
查找图书操作
- 查找有的图书:
- 查找没有的图书
新增图书操作
展示图书操作
删除图书操作
- 删除有的图书
- 删除没有的图书
普通用户功能测试
查找图书操作
借阅图书操作
归还图书操作
当还完继续还的时候
当还的书书架上没有的时候
面向对象编程思想的体现
类的定义和对象的创建
- 我们定义一个"Book"类来表示图书的属性和行为
- 我们定义一个"BookList"类来表示存放图书的书架的属性和行为
- 我们默认书架上有5本书,一开始就创建了5个Book对象
- 我们每一次新增图书的时候都会再创建一个图书对象,并把这个对象放入书架上
封装
在上面的例子中,我们使用了封装来隐藏Book类的内部实现细节。图书的属性(书名、作者、价格、类型、是否被借出)都被声明为私有(private),这意味着它们不能直接从外部访问。我们为每一个属性都提供了公共的(getter/setter)方法来让外部代码访问这些属性的值。
get是得到属性的值,set是设置属性的值
继承
我们的管理员和普通用户都有一些共性:都有名字,都会生产一个可以选择操作的菜单,两者的行为其实是一样的,只是可以操作的选项不同。所以我们在User类中把这些全定义好,通过管理员和普通用户来继承实现这些功能。
多态
在系统中,我们选择不同的用户类型会出现不同的功能菜单。是因为我们对menu这个方法进行了重写,不同的对象调用这个方法会执行自己重写了的逻辑和功能。
通过使用多态,我们可以使用相同的方法处理不同类型的对象,这样代码更加灵活和可复用。
抽象类
在上面的例子中,我们已经看到了Java中的抽象类的使用。在这个示例中,User类被声明为抽象类,它是一种抽象的概念,它表示用户的通用属性。
接口
在上面的示例中,我们把所有的操作定义成了一个接口,我们定义IOperation接口就是进行所有的功能操作,然后通过不同的类来分别实现各自的功能。通过这个接口我们可以控制所有的功能。
总结
这个简单的图书管理系统演示了Java面向对象编程的各个概念的应用。实际的项目中,面向对象编程将更复杂和丰富,但这个示例可以帮助你理解如何在实际项目中应用面向对象编程的概念。
相关文章:

Java面向对象编程实战详解(图书管理系统示例)
文章目录 面向编程概念图书管理系统示例需求分析设计阶段编码实现创建目录结构Book类的编码BookList类的编码User类的编码AdminUser类的编码NormalUser类的编码启动类的编写具体的操作实现IOperation接口新增图书的实现借阅图书的实现删除图书的实现显示图书的实现查找图书的实…...
ubuntu设置主机ip
ubuntu 设置ip sudo dhclient -r enp67s0 # 是你的网卡,可以通过ifconfig 查,比如enp0 sudo ifconfig enp67s0 192.168.1.114 netmask 255.255.255.0 Ubuntu显示有线网已连接但无法上网,已经确认网口、交换机(路由器ÿ…...

CleanMyMac X4.14.1中文版如何清理 Mac系统?CleanMyMac 真的能断网激活吗?
CleanMyMac X4.14.1中文版如何清理 Mac系统?Mac系统在使用过程中都会产生大量系统垃圾,如不需要的系统语言安装包,视频网站缓存文件,mac软件卸载残留的注册表等。 随着时间推移,mac系统垃圾就会越来越多,电…...

详细介绍 React 中如何使用 redux
在使用之前要先了解它的配套插件: 在React中使用redux,官方要求安装其他插件 Redux Toolkit 和 react-redux Redux Toolkit:它是一个官方推荐的工具集,旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具…...

VLOOKUP多条件查询
LOOKUP(1,0/((A3:A15A18)*(C3:C15C18)),F3:F15)...
分页插件Mybatis
<plugins><!-- com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor"com.github.pagehelper.PageInterceptor"><!-- 配置方言:告诉分页插件使用底层数据库是什么--><property name"helperDialect" value"…...

AXI协议之AXILite开发设计(四)—Block Design使用
微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 2、AXI interconnect互联组件的使用…...

音视频——帧内预测
H264编码(帧内预测) 在帧内预测模式中,预测块P是基于已编码重建块和当前块形成的。对亮度像素而言,P块用于44子块或者1616宏块的相关操作。44亮度子块有9种可选预测模式,独立预测每一个44亮度子块,适用于带有大量细节的图像编码&…...

2.uni-app项目文件
uni-app像是vue与微信小程序的合体,使用 uni-ui项目 模板创建的项目文件如下 目录 1 pages 2 pages.json 3 App.vue 4 index.html 5 static 6 uni_modules 7 manifest.json 8 main.js 9 uni.scss 1 pages 这个是放页面的,默认里面有…...

JavaScript学习 -- 对称加密算法DES
在现代的互联网时代,数据安全性备受关注。为了保护敏感数据的机密性,对称加密算法是一种常用的方法。在JavaScript中,DES(Data Encryption Standard)是一种常用的对称加密算法。本篇博客将为您展示如何在JavaScript中使…...

【Python数据分析】Python常用内置函数(二)
🎉欢迎来到Python专栏~Python常用内置函数(二) ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:Python学习专栏 文章作者技术和水平有限,如果文…...
Api接口出现Required request body is missing的解决方法
目录 1.问题所示2.原理分析3.解决方法1.问题所示 在使用PostMan 测试接口的时候,出现如下问题: {"code": 400,"success": false,"data": {},"msg":...

【Kaggle】Kaggle数据集如何使用命令语句下载?
一、Kaggle数据集如何下载 1.1 问题的起因 最近看到了 Google 组织的 Kaggle 比赛,想自己试一下,但是数据集太大了,将近有370G的数据。直接下载的话,网速太慢,可能要下载3-4天,所以萌生了用命令语句下载的…...
android pdf框架,编译mupdf
因为mupdf编译的体积不小,之前也发过编译的文章,现在更新一下. 建一个mupdf_c目录,名字自己取,在里面git下载mupdf源码,把目录修改为libmupdf mupdf_c目录下建build.gradle文件,内容如下 apply plugin: com.android.library apply plugin: maven-publishgroup com.artifex.…...

线性表详细讲解
2.1 线性表的定义和特点2.2 案例引入2.3 线程表的类型定义2.4 线性表的顺序表示和实现2.4.1 线性表的顺序存储表示2.4.2 线性表的结构类型定义2.4.3 顺序表基本操作的实现2.4.4 顺序表总结 2.5 线性表的链式表示和实现2.5.1 线性表的链式存储表示2.5.2 单链表的实现(…...
代码随想录算法训练营day45
文章目录 Day45爬楼梯题目思路代码 零钱兑换题目思路代码 完全平方数题目思路代码 Day45 爬楼梯 70. 爬楼梯 - 力扣(LeetCode) 题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢…...

机器学习深度学习——softmax回归(上)
👨🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——线性回归的简洁实现 📚订阅专栏:机器学习&&深度学习 希望文章对你们有所…...
基于express调用chatgpt文字流输出和有道智云语音合成
express是基于node.js的一个web框架,可以更加简洁的去创建一个后台服务,由于项目的需要,引入和typescript,经过几天的努力实现了chatgpt文字流输出有道智云语音合成的结合(略有遗憾),下面我记载…...

(学习笔记-内存管理)内存分段、分页、管理与布局
内存分段 程序是由若干个逻辑分段组成的,比如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就用分段的形式把这些分段分离出来。 分段机制下,虚拟地址和物理地址是如何映射的? 分段机制下的虚拟地址由…...

PHP使用Redis实战实录1:宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案
宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案 前言一、Redis安装部署1.安装Redis2.php安装Redis扩展3.启动Redis 二、避坑指南1.6379端口配置2.Redis服务启动(1)Redis服务启动失败(2)Redis启动日志排查(3&a…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
起重机起升机构的安全装置有哪些?
起重机起升机构的安全装置是保障吊装作业安全的关键部件,主要用于防止超载、失控、断绳等危险情况。以下是常见的安全装置及其功能和原理: 一、超载保护装置(核心安全装置) 1. 起重量限制器 功能:实时监测起升载荷&a…...

【Java多线程从青铜到王者】单例设计模式(八)
wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本,sleep也是可以指定时间的,也就是说时间一到就会解除阻塞,继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒),wait能被notify提前唤醒…...
C#最佳实践:为何优先使用as或is而非强制转换
C#最佳实践:为何优先使用as或is而非强制转换 在 C# 的编程世界里,类型转换是我们经常会遇到的操作。就像在现实生活中,我们可能需要把不同形状的物品重新整理归类一样,在代码里,我们也常常需要将一个数据类型转换为另…...