图书管理系统——java基础(源码)后续引入数据库,Swing程序设计,支持关注!后续更新……

         学了java想要练手,图书管理系统这个项目非常适合你

项目需求大体想法:

能够查看书籍,借阅书籍,打印书籍等功能。输出姓名后能进入为普通用户模式或者管理员模式。

各类包之间协同合作之间关系讲解。

做这个项目的始终是为了对于刚学java的同学,在学完面向对象,和一部分类和枚举,异常学完之后就可以尝试了。

这个项目没有多高大,这不过是对java基础知识的巩固,没有Swing图形界面,和前端知识,也没有引入数据库的知识jdbc。但是毕竟是项目,难度还是有的,对于初学者来说既能巩固知识,又能拓展思维,学会这个项目,期末考试考个90+不成问题,而且对后期真正项目起到很好的帮助。

一 .整体思路

书籍类为书籍的封装信息,和返回信息。有书,也要有书架,书架就是存放书籍的具体信息。至于为什么会有书架和书籍类之分,那就与代码可维护性,功能分析有很好作用。对于接口,就是具体代码实现了,像打印书籍,归还书籍,停止退出系统,查找书籍,增加书籍,删除书籍。在上面我说过有普通用户和管理员之分,那么就有这两类,这两类是实现菜单打印,和连接接口的功能。

(1)书籍包

键一个book包

Book是书籍类

这是基本书籍封装信息:

package book;

public class Book {
    private String name; //书名
    private String author;  //作者
    private String dynasty;  //朝代
    private int price;  // 价格
    private boolean isBorrowed;      //是否借出
    private String type;  //类型
}

然而封装的数据我们要使用必须用公开的方法来实现


    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 String getDynasty() {
        return dynasty;
    }

    public void setDynasty(String dynasty) {
        this.dynasty = dynasty;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

上面的方法你准备怎么写呢?不会一步一步敲出来把?!

①点击鼠标右键,弹出generate,点击

②弹出getter and setter,点击

进入之后全选后确定就会出现我们想要的方法了

上面是对Book类的部分代码,当我们有需要时再去修改,跟着我的思路来才是一个程序员思维提升的好方法。

BookList是书架类

书架类我们首先做的就是建立动态数组,为了存储书籍,这里用到了数组的知识。

package book;


public class BookList {
    //建立一个动态数组存放信息
    //书架存放Book里面的书籍信息,那么该书籍是Book数组
   // private Book[]books=new Book[10];这样做可维护性不高所以把10改成
    private static final int number=20;
    private Book[]books=new Book[number];
    private int usedSize;
    public BookList(){
        books[0]=new Book("三国演义","罗贯中","明代","小说",520);
        books[1]=new Book("红楼梦","曹雪芹","清朝","小说",521);
        books[2]=new Book("西游记","不知道","明代","小说",250);
        this.usedSize=3;

    }

在这段代码中开辟了存放20的数组,下面的代码则是对书架中书籍的具体化,但是,在Book类中我们没有构建有参的构造方法,所以要加上。

  public Book(String name, String author, String dynasty, String type, int price) {
        this.name = name;
        this.author = author;
        this.dynasty = dynasty;
        this.type = type;
        this.price = price;

    }

(2)用户包

新建一个userall1包

建一个User抽象类

package userall1;
import book.*;
import opera.IPinterfrance;


//抽象类---》用户
public abstract class User {
    //写一个姓名
    protected String name;  //子类无法继承
    public User(String name){
        this.name=name;
    }
    //写了一个抽象方法菜单
    public abstract int menu();
}

建一个AdminUser管理员子类

package userall1;
import opera.*;

import java.util.*;
//AdmiinUser是User的子类
public class AdminUser extends User{
    public AdminUser(String name) {
        super(name);
}

建一个NormalUser普通用户子类

package userall1;

import opera.*;

import java.util.Scanner;

public class NormalUser extends User{
    public NormalUser (String name){
        super(name);
}

建立用户包的目的是为了区分管理员还是普通用户,并在本类中实现特定的功能。到这里代码还没有完全实现,思路要一步一步来,这里这不过是输入名字后,保存名字信息。

(三)主函数

程序的开始是主函数,代码就是在主函数开始调试的,当你不明白带代码是你就要从主函数一步一步开始分析。

先对主函数进行分析大体了解流程,接口中的具体实现方法最后看。因为他对全局影响不大。

在主函数中写一个登录方法

public class Main {
    //写一个登录类,返回值是User,请输入你的名字,选择身份
    //static为什么要用static与后面有关
    public static User login() {
        System.out.println("请输入你的姓名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();//输入字符串scanner.nextLine()
        System.out.println("请输入你的身份:1-》管理员 2-》普通用户");
        int choice = scanner.nextInt();
        if (choice == 1) {
            return new AdminUser(name);  //下面子类通过父类继承
        }
        if (choice == 2) {
            return new NormalUser(name);
        } else {
            System.out.println("输入错误!");

            return  login();

        }

    }

主方法里面要调用登录方法。

    public static void main(String[] args){
            User user = login();  //login()返回后是new AdminUser(name)父类通过子类实例化
            BookList bookList=new BookList();
            while(true)
            {
                int choice=user.menu();
                user.dowork(choice,bookList);

            }


        }
    

在主方法中我们看到user.menu(),所以user中要有抽象方法menu。dowork,而dowork方法是从user里调用的,目的是为了什么呢?我们加上代码

menu

user:

管理员具体菜单代码:

public int menu(){
        System.out.println("____________________________________");
        System.out.println("1.查找图书");
        System.out.println("2.新增图书");
        System.out.println("3.删除图书");
        System.out.println("4.显示图书");
        System.out.println("0.退出系统");
        
}

普通用户菜单代码:

    public int menu(){
        System.out.println("_________________");
        System.out.println("hello,"+name+"~");
        System.out.println("1.查找图书!");
        System.out.println("2.借阅图书!");
        System.out.println("3.归还图书!");
        System.out.println("0.退出系统!");
}

光有菜单还不行,还要输入数字,输入数字后转接到具体实现类,那么就要再一次引入数组,通过数组下标来实现接口连接

在user引入:

在管理员类普通用户类中还要引入:

this.ioPerations = new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new BrrowOperation(),
                new ReturnOperation(),     //为什么会放在子类因为子类接口不相同
                //以动态方式申请内存。拿到变量后,我们就给他们分配内存
        };

具体实现代码:

user:

普通用户和管理员都要在菜单下面加入输入数字语句:

      Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;

(四)接口实现包

建一个接口Ipinterfrance,为了实现各个功能的。

package opera;

import book.BookList;

import java.sql.SQLException;

//接口实现普通用户和管理员的功能
public interface IOPeration {
    //抽象方法功能是针对图书的
    void work(BookList bookList) throws ClassNotFoundException, SQLException;
}

二 .具体接口代码

(1)展示图书

package opera;
import book.*;
public class Showopera implements IPinterfrance{
    public void work(BookList bookList){   //传入图书变量
        System.out.println("展示图书!");
        int current=bookList.getUsedSize();
        for(int i=0;i<current;++i)
        {
            System.out.println(bookList.getBooks(i));

        }
    }


}

(2)增加图书

package opera;
import book.*;

import java.sql.*;
import java.util.*;
public class AddOperation implements IOPeration{


    //重写方法
    @Override
    public void work(BookList bookList) throws ClassNotFoundException, SQLException {
        System.out.println("新增图书!");
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入新增图书名字:");
        String name=scanner.nextLine();
        System.out.println("请输入新增图书作者:");
        String auther=scanner.nextLine();
        System.out.println("请输入新增图书价格:");
        int price=scanner.nextInt();
        Scanner scanner2=new Scanner(System.in);
        System.out.println("请输入新增图书类型:");
        String type=scanner2.nextLine();
       System.out.println("请输入新增图书作者朝代:");
       String dynasty=scanner2.nextLine();
 Book book=new Book(name,auther,dynasty,price,type);
        int currentSize= bookList.getUsedSize();
        for(int i=0;i<currentSize;++i){
            Book temp=bookList.getBooks(i);  //为什么会不同?? temp不行
            if(temp.getName().equals(name)){//判断查找图书名字是否相同
                System.out.println("已经有这本书了");
                return;
            }
        }
        bookList.setBooks(book);
        System.out.println("新增图书成功");
        //新图书+1
        bookList.setUsedSize(currentSize+1);
    }
}

这里的setBooks是书架类里面新增图书的方法:

(3)停止系统

停止系统非常简单,就是:

package opera;

import book.BookList;

public class ExitOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("退出系统!");
        System.exit(0); //退出系统
    }
}

(4)借阅系统

package opera;

import book.BookList;
import java.util.*;
import book.*;
public class BrrowOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("借阅图书");
        System.out.println("请输入要借阅的图书");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int curentSize= bookList.getUsedSize();
        int x=1;
        for(int i=0;i<curentSize;i++){
            Book temp=bookList.getBooks(i);
            if((temp.getName().equals(name))&&!temp.isBorrowed()){  //
                {

                    temp.setBorrowed(true);
                    x=0;
                    System.out.println("借阅成功!");
                    return;
                }
            }
        }
        if(x==1){
            //写了个判断条件让我想到了冒泡排序
            System.out.println("没有该图书");
        }

    }
}

(5)归还图书

package opera;

import book.BookList;
import java.util.*;
import book.*;

public class ReturnOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("归还图书!");
        System.out.println("请输入要归还的图书名字:");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int curentSize= bookList.getUsedSize();
        for(int i=0;i<curentSize;i++){
            Book temp=bookList.getBooks(i);
            if((temp.getName().equals(name))&&temp.isBorrowed()){
                {
                    temp.setBorrowed(false);//变成归还状态false
                    System.out.println("归还成功!");
                    return;
                }
            }
        }


    }
}

(6)查找书籍

package opera;

import book.*;

import java.util.Scanner;

public class FindOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("查找图书!");
        System.out.println("请输入要输入的图书");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int currentSize= bookList.getUsedSize();
        for(int i=0;i<currentSize;++i)
        {
            Book book=bookList.getBooks(i);
            if(book.getName().equals(name))  //判断书籍是否相同
            {
                System.out.println("找到了");
                System.out.println(book);
                return;
            }

        }
        System.out.println("没有这本书");

    }
}

(7)删除书籍

package opera;

import book.*;
import java.util.*;
public class DelOperation implements IOPeration{
    @Override
    public void work(BookList bookList) {
        System.out.println("删除图书!");
        System.out.println("请输入要删除的图书名字");
        Scanner scanner=new Scanner(System.in);
        String name=scanner.nextLine();
        int currentSize= bookList.getUsedSize();
        int index=-1;
        //删除的思路很简单就是减小下标很粗暴
        for(int i=0;i<currentSize;i++){
            Book temp=bookList.getBooks(i);
            if(temp.getName().equals(name))
            {
                index=i;
                break;
            }
            for(int j=index;j<currentSize;j++)
            {
                Book book=bookList.getBooks(j+1);
                bookList.setBooks(j,book);  //把上面的数放到该位置为以后-1做铺垫
            }
        }


        bookList.setUsedSize(currentSize-1);//修改size值
        bookList.setBooks(currentSize-1,null);//因为删除的是对象,所以把地址置为null,就没有人引用了

    }

}

三 .疑难分析(看了5k点赞的看不懂的这里都有详细讲解

如果对这个项目很熟悉的话,直接看我的源码和疑难分析。

这段代码就是显示代码执行的,通过书架类中getbooks方法调用

如果对这个项目有所疑问请私信我,大家一定要捋一下代码,不会的地方私信我或者在评论区留言我一定会给大家回复!!!

四 .源码展示

主方法代码:

book包

Book类

package book;

public class Book {


    //书的名字,类型,作者,价格,是否借出
    private String name;
    private String author;
    private double price;
    private boolean isBorrowed;//是否借出
    private String type;
//此处点击鼠标,generate +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 double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
    //写一个构造方法不是特别明白
   public Book(String name,String author,double price,String type){
        this.author=author;
        this.name=name;
        this.type=type;
        this.price=price;

   }
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ", isBorrowed=" +(isBorrowed==true?"    已借出":"    未借出") +
                '}';
    }
    }

BookList类

package book;
import java.sql.*;
//写一个书架
public class BookList {

    //写数组 数据类型[]变量名=new 数据类型[大小]
    //private Book[]books=new Book[10];
    //上面的写法会可写性不高
    private static final int DEFAULT_SIZE=10;
    private Book[]books=new Book[DEFAULT_SIZE];
    private int usedSize;
    //虽然可以在类中直接初始化变量,但不定义构造方法可能会导致初始化逻辑分散
    // 和不清晰。构造方法提供了一种清晰、集中的方式来初始化对象的状态,
    // 这对于保持代码的组织、可读性和可维护性至关重要。
    public BookList(){
        books[0]=new Book("三国演义","罗贯中",55,"小说");
        books[1]=new Book("红楼梦","曹雪芹",50,"小说");
        books[2]=new Book("三国志","陈寿",58,"史书");
        this.usedSize=3;
    }

    public Book getBooks(int pos) {
        return this.books[pos];
    } //显示数据
    //记录当前数组有几本书
    //记录当前数组


   public void setBooks(Book book){
        this.books[usedSize]=book;
    } //通过这个方法增加书籍到这里面
    public void setBooks(int pos,Book book) {
        this.books[pos] = book;
    }


    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }



}

user包

管理员类

package users;

import java.util.Scanner;
import opera.*;
public class AdminUser extends User{
    public AdminUser(String name){
        super(name);
        this.ioPerations=new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new ShowOperation()    //难于理解
        };
        }
    public int menu(){
        System.out.println("____________________________________");
        System.out.println("1.查找图书");
        System.out.println("2.新增图书");
        System.out.println("3.删除图书");
        System.out.println("4.显示图书");
        System.out.println("0.退出系统");
        System.out.println("请输入序号:");
        Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;
    }
}

普通用户类

package users;

import java.util.Scanner;
import opera.*;//包里面全部调用
public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
        //动态开辟数组
        this.ioPerations = new IOPeration[]{//引用,这边用super也可以,因为这里没有同名的,不需要做区分。用this最好
                new ExitOperation(),
                new FindOperation(),
                new BrrowOperation(),
                new ReturnOperation(),     //为什么会放在子类因为子类接口不相同
                //以动态方式申请内存。拿到变量后,我们就给他们分配内存
        };
    }
    public int menu(){
        System.out.println("_________________");
        System.out.println("hello,"+name+"~");
        System.out.println("1.查找图书!");
        System.out.println("2.借阅图书!");
        System.out.println("3.归还图书!");
        System.out.println("0.退出系统!");
        System.out.println("请输入序号:");
        Scanner scanner=new Scanner(System.in);
        int choice=scanner.nextInt();
        return choice;
    }
}

User抽象类

package users;
import opera.*;
import book.*;

import java.sql.SQLException;

public abstract class User { //抽象类
    protected String name; //不能为私有,否则管理员类或者普通类无法继承
    protected IOPeration[] ioPerations;//定义了数组
    //构造方法
    public User(String name){
        this.name=name;
    }
    public void doWork(int choice, BookList bookList) throws SQLException, ClassNotFoundException {//通过选择的操作,去选择执行数组下的哪个操作
        this.ioPerations[choice].work(bookList);
    }

    public abstract int menu();
}

接口

package opera;

import book.BookList;

import java.sql.SQLException;

//接口实现普通用户和管理员的功能
public interface IOPeration {
    //抽象方法功能是针对图书的
    void work(BookList bookList) throws ClassNotFoundException, SQLException;
}

具体代码上面已经给出不在重复展现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新疆 | 金石商砼效率革命背后的逻辑

走进标杆企业&#xff0c;感受名企力量&#xff0c;探寻学习优秀企业领先之道。 本期要跟砼行们推介的标杆企业是新疆砼行业的龙头企业&#xff1a;新疆兵团建工金石商品混凝土有限责任公司&#xff08;以下简称&#xff1a;新疆金石&#xff09;。 从年产80万方到120万方&am…

计算机图形学入门03:基本变换

变换(Transformation)可分为模型(Model)变换和视图(Viewing)变换。在3D虚拟场景中相机的移动和旋转&#xff0c;角色人物动画都需要变换&#xff0c;用来描述物体运动。将三维世界投影变换到2D屏幕上成像出来&#xff0c;也需要变换。 1.二维变换 1.1缩放变换 如上图所示&…

自动化测试-ddt数据驱动yaml文件实战(详细)

前言 ddt 驱动 yaml/yml 文件来实现数据驱动测试 ddt.file_data&#xff1a;装饰测试方法&#xff0c;参数是文件名。文件可以是 json 或者 yaml 类型。 注意&#xff1a;如果文件是以 “.yml”或者".yaml" 结尾&#xff0c;ddt 会作为 yaml 类型处理&#xff0c;…

期权与股票在交易上是有什么区别吗?

国内的股票市场&#xff0c;只能做多&#xff0c;T1交易。期权则分为4个方向&#xff0c;买入看涨期权&#xff0c;买入看跌期权&#xff0c;也就是做多和做空T0双向交易&#xff0c;同时每个方向还区分不同的行权价&#xff0c;每个行权价对应的4个方向的期权&#xff0c;都有…

精通推荐算法6:用户行为序列建模 -- 总体架构

1 行为序列建模技术架构 身处目前这个信息爆炸的时代&#xff0c;用户在各推荐场景上有丰富的行为序列。将行为序列特征引入推荐算法中&#xff0c;有利于丰富特征工程体系、获得更立体和更全面的信息&#xff0c;同时可以表达用户兴趣演化过程&#xff0c;并捕获用户实时兴趣…

取代或转型?人工智能对软件测试的影响(内附工具推荐)

在当今快速发展的数字环境中&#xff0c;从移动App到基于Web的平台&#xff0c;软件已成为我们日常生活和工作不可或缺的一部分。然而&#xff0c;随着软件系统变得越来越复杂&#xff0c;如何确保其质量和可靠性已成为开发人员和测试人员所面临的一大重要挑战。 这就是软件测…

python探索时钟模拟之旅:从设计到实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、设计时钟类 三、代码实现 四、扩展功能&#xff1a;指定步数后自动停止 五…

<Transition> expects exactly one child element or component.

近日在vue中使用 Transition 标签是发生了如下报错&#xff1a; [plugin:vite:vue] expects exactly one child element or component. 原因&#xff1a; 仅支持单个元素或组件作为其插槽内容。如果内容是一个组件&#xff0c;这个组件必须仅有一个根元素。 原始代码&#xff1…

【产品经理】技术知识

引言&#xff1a;        在最近频繁的产品管理职位面试中&#xff0c;我深刻体会到了作为产品经理需要的不仅仅是对市场和技术的敏锐洞察&#xff0c;更多的是在复杂多变的环境中&#xff0c;如何运用沟通、领导力和决策能力来引导产品从概念走向市场。这一系列博客将分享…

应急通信保障之多链路聚合通信设备在应急救援实施中的解决方案

在当今信息化社会&#xff0c;应急通信保障已成为各类救援任务中不可或缺的一环。尤其在复杂多变的应急救援现场&#xff0c;如何确保通信畅通、信息传递及时&#xff0c;直接关系到救援行动的成败。近年来&#xff0c;多链路聚合通信设备以其独特的优势&#xff0c;逐渐在应急…

一款超好用的国产Redis可视化工具

一、简介 1、这是一款追求极致性能&#xff08;它可以支持前面100万数据的展示。&#xff09;海量数据下低内存占用、极简布局、高效交互、跨平台、支持反序列化Java字节码的redis可视化客户端工具。 支持三大操作系统Windows、MacOS、Linux&#xff0c;适合不同操作系统口味的…

网络延迟监控

网络中的延迟是指数据通过网络传输到其预期目的地所需的时间&#xff0c;它通常表示为往返延迟&#xff0c;即数据从一个位置传输到另一个位置所需的时间。 网络延迟&#xff08;也称为滞后&#xff09;定义为数据包通过多个网络设备进行封装、传输和处理&#xff0c;直到到达…

linux镜像虚拟机创建共享文件夹详细步骤 -- 和本地电脑传输文件

主机与虚拟机之间传递文件&#xff0c;最快捷的方法莫过于共享文件夹。此方法不需要复制文件&#xff0c;而且可以节省硬盘空间。 具体设置步骤如下&#xff1a; 打开自己的电脑&#xff0c;创建共享的文件夹&#xff0c;完成后鼠标右击刚刚创建的共享文件夹&#xff0c;选择…

《C语言深度解剖》(16):C语言的文件读写操作

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏链接查看&…

RTPS协议之Messages Module

目录 Messages ModuleType定义RTPS消息结构RTPS消息头子消息结构 RTPS消息接收者SubmessageElementsRTPS HeaderRTPS Submessages Messages Module RTPS Writer和RTPS Reader之间的交换数据的消息。 Type定义 TypePurposeProtocolId_tSubmessageFlagsub msg flagSubmessageK…

【c++】继承学习(三)菱形继承的挑战与虚拟继承的策略

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章来讲解继承的第三部分&#xff0c;有关多继承和菱形继承的内容 目录 1.菱形继承2.虚拟继承3.虚拟继承解决数据冗余和二义性的原理4.继承的总结和反思继承…

外汇天眼:PayPoint投资100万英镑,深化与Aperidata开放银行合作

PayPoint今日宣布对Aperidata Ltd进行100万英镑的投资&#xff0c;Aperidata是一家创新的消费者和商业信用报告及开放银行平台。 此交易将使PayPoint集团在两家公司之间现有的商业合作基础上更进一步&#xff0c;为包括政府、地方当局、慈善机构和住房协会在内的多个领域的客户…

Java 五种内部类演示及底层原理详解

内部类 什么是内部类 在A类的内部定义B类&#xff0c;B类就被称为内部类 发动机类单独存在没有意义 发动机为独立个体 可以在外部其他类里创建内部类的对象去调用方法 类的五大成员 属性 方法 构造方法 代码块 内部类 内部类的访问特点 内部类可以直接访问外部类的成员&a…

海外代理IP适用业务是哪些?

在当今数字化时代&#xff0c;互联网已经成为商业和个人生活不可或缺的一部分。IP代理作为出海业务的神器之一&#xff0c;备受跨境出海业务人员关注。IPFoxy动态、静态纯净代理IP也根据业务需求的不同&#xff0c;分为静态住宅、动态住宅、静态IPv4、静态IPv6四种类型代理。那…

基于Spring Cloud微服务架构的Java CRM客户关系管理系统源码

在当今竞争激烈的市场环境中&#xff0c;企业要想保持持续的增长和稳定的客户基础&#xff0c;高效管理客户关系显得尤为重要。CRM&#xff08;客户关系管理&#xff09;系统作为一种先进的管理工具&#xff0c;正逐渐成为企业不可或缺的一部分。该系统通过集成销售、市场、服务…