Java中规模软件开发实训——掌握财务自由的关键!解锁智能家庭记账系统的神奇力量!(家庭记账软件)

news2024/11/25 23:01:08

博主:命运之光

🌸专栏:Python星辰秘典

🐳专栏:web开发(html css js)

❤️专栏:Java经典程序设计

☀️博主的其他文章:点击进入博主的主页

前言:财务自由,理想生活的关键之一就是有效的财务管理。但是,很多人在家庭记账上遇到了困惑和挑战。幸运的是,我设计了一个令人惊叹的家庭记账管理系统,它将帮助您轻松解决这些问题。在这篇博客中,我将带您深入了解这个系统的设计流程和功能,让您体验到一种全新的、智能化的财务管理方式。无论您是要控制支出、追踪收入,还是实现财务目标,本系统都将成为您不可或缺的伙伴。让我们一同探索,让财务管理变得简单、高效、乐趣十足! 

目录

☀️项目一:家庭记账软件

🐳一、 实验内容

二、 问题描述

三、 项目功能

四、 项目分析

五、 项目设计

六、 系统实现

七、总结


☀️项目一:家庭记账软件

🐳一、 实验内容

《家庭记账管理软件》是一个利用Java Swing图形界面创建的应用程序,旨在帮助家庭记录和管理收入和支出,并提供支出明细表的打印功能。

该软件具有以下主要功能:

用户界面:软件使用Java Swing库创建图形用户界面,提供友好的操作界面,使用户能够轻松输入和管理家庭的财务信息。

记录收入和支出:用户可以输入家庭的收入和支出信息,包括金额、收入来源等。例如,他们可以输入薪水、租金、水电费、购物开销等。

支出明细表:软件可以生成支出明细表,其中包括每笔支出的详细信息,如金额、分类等。用户可以选择打印该明细表,以便于记录和审查家庭的支出情况。

通过实现这些功能,该《家庭记账管理软件》可以帮助用户记录和管理家庭的收入和支出,提供财务统计信息,并提供支出明细表的打印功能,以便用户更好地管理和掌握家庭的财务状况。

🐳二、 问题描述

该项目旨在解决以下问题:

家庭财务管理:许多家庭需要有效地管理他们的财务状况,包括收入和支出的记录、统计和分析。该软件提供了一个方便的平台,让家庭成员能够轻松地记录和管理他们的财务信息。

支出控制和预算:通过记录和分类支出,家庭成员可以更好地控制他们的开支,并制定合理的预算。软件提供的统计信息和支出明细表可以帮助用户了解他们的消费习惯和开支情况,从而更好地进行预算规划。

财务透明度和沟通:对于多人共同生活的家庭,财务透明度和沟通非常重要。该软件允许家庭成员共享和访问相同的账户信息,使他们能够更好地了解家庭的财务状况,提高沟通和决策效率。

记账方便性:传统的手写记账可能繁琐且容易出错,而该软件提供了一个简单直观的图形界面,使记账变得更加方便和准确。用户可以通过输入相关信息,快速记录收入和支出,而且软件会自动计算和管理数据。

通过解决这些问题,该《家庭记账管理软件》可以帮助家庭成员更好地管理他们的财务,提高财务规划和控制的效率,并促进家庭内部的财务透明度和沟通。

🐳三、 项目功能

(1)用户界面

软件使用Java Swing库创建图形用户界面,提供友好的操作界面,使用户能够轻松输入和管理家庭的财务信息。

(2)记录收入和支出

用户可以输入家庭的收入和支出信息,包括金额、收入来源等。例如,他们可以输入薪水、租金、水电费、购物开销等。

登记收入

登记支出

(3)支出明细表

软件可以生成支出明细表,其中包括每笔支出的详细信息,如金额、分类等。用户可以选择打印该明细表,以便于记录和审查家庭的支出情况。

通过这个《家庭记账管理软件》,家庭成员可以方便地记录和管理他们的财务信息,有助于更好地掌握和规划家庭的经济状况。

🐳四、 项目分析

(1)用户界面:在主界面上,用户可以看到收支明细、登记收入、登记支出和清空记录等统计信息的摘要。还可以选择添加新的收入或支出,查看支出明细表或打印支出明细。

(2)登记收入按钮:点击登录收入按钮会弹出对话框,对话框中可以录入收入来源和金额两个信息,点击确定信息录入,点击取消关闭对话框。

点击确定按钮后会显示收入已登记。

(3)登记支出按钮:点击登录支出按钮会弹出对话框,对话框中可以录入支出来源和金额两个信息,点击确定信息录入,点击取消关闭对话框。

点击确定按钮后会显示支出已登记。

(4)收支明细按钮:点击按钮会弹出收支明细页面,页面中详细显示出录入的收入信息和录入的支出信息,具体样式如下图所示:

点击确定按钮或者右上角的叉号关闭收入明细对话框。

(5)清空记录按钮:用于清空输入的数据,用于重新输入新的数据。

点击确认按钮进行录入信息的清除。

信息清楚成功,再次点击收支明细按钮进行检验。

信息清除完毕。

🐳五、 项目设计

🐳六、 系统实现

🌸项目源代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class FamilyAccountingSystem extends JFrame {
    private double baseAmount; // 基本金
    private List<Expense> expenseList; // 支出列表
    private List<Income> incomeList; // 收入列表

    private JButton showDetailsButton; // 显示明细按钮
    private JButton addIncomeButton; // 添加收入按钮
    private JButton addExpenseButton; // 添加支出按钮
    private JButton clearRecordsButton; // 清空记录按钮

    public FamilyAccountingSystem() {
        setTitle("家庭记账管理系统"); // 设置窗口标题
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗口关闭操作为退出程序
        setLayout(null); // 设置布局管理器为null,使用自定义布局
        // 创建一个带背景图的JPanel作为容器
        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                // 加载背景图像并绘制到JPanel上
                Image backgroundImage = new ImageIcon("3.jpg").getImage();
                g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), null);
            }
        };
        setContentPane(panel); // 设置窗口内容面板为自定义的JPanel
        setLayout(new GridBagLayout()); // 设置布局管理器为GridBagLayout

        // 创建一个JLabel用于显示"家庭记账管理系统"
        JLabel titleLabel = new JLabel("家庭记账管理系统");
        titleLabel.setFont(new Font("黑体", Font.BOLD, 20));
        titleLabel.setHorizontalAlignment(JLabel.CENTER);

        // 设置GridBagLayout布局管理器
        setLayout(new GridBagLayout());

        // 创建GridBagConstraints对象,用于设置组件的约束条件
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.gridwidth = GridBagConstraints.REMAINDER; // 占据整行
        constraints.insets = new Insets(-100, 10, 0, 10); // 设置组件的内边距

        // 将titleLabel添加到界面中
        add(titleLabel, constraints);

        baseAmount = 10000.0; // 设置初始基本金
        expenseList = new ArrayList<>(); // 创建支出列表
        incomeList = new ArrayList<>(); // 创建收入列表

        // 创建按钮并设置字体样式
        showDetailsButton = new JButton("收支明细");
        addIncomeButton = new JButton("登记收入");
        addExpenseButton = new JButton("登记支出");
        clearRecordsButton = new JButton("清空记录");

        showDetailsButton.setFont(new Font("黑体", Font.BOLD, 16));
        addIncomeButton.setFont(new Font("黑体", Font.BOLD, 16));
        addExpenseButton.setFont(new Font("黑体", Font.BOLD, 16));
        clearRecordsButton.setFont(new Font("黑体", Font.BOLD, 16));

        // 创建按钮的约束条件对象
        GridBagConstraints buttonConstraints = new GridBagConstraints();
        buttonConstraints.gridx = 0;
        buttonConstraints.gridy = 0;
        buttonConstraints.insets = new Insets(10, 10, 10, 10); // 设置按钮的内边距
        buttonConstraints.ipadx = 20;
        buttonConstraints.ipady = 10;

        // 将按钮添加到界面中
        add(showDetailsButton, buttonConstraints);

        buttonConstraints.gridy = 1;
        add(addIncomeButton, buttonConstraints);

        buttonConstraints.gridy = 2;
        add(addExpenseButton, buttonConstraints);

        buttonConstraints.gridy = 3;
        add(clearRecordsButton, buttonConstraints);

        // 为按钮添加事件监听器
        showDetailsButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showDetails();
            }
        });

        addIncomeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showIncomeDialog();
            }
        });

        addExpenseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showExpenseDialog();
            }
        });

        clearRecordsButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                clearRecords();
            }
        });

        pack(); // 调整窗口大小以适应组件
        setSize(600, 400); // 设置窗口大小
        setLocationRelativeTo(null); // 将窗口居中显示
    }


    // 显示收支明细的方法
    private void showDetails() {
        StringBuilder report = new StringBuilder(); // 创建一个字符串构建器
        DecimalFormat decimalFormat = new DecimalFormat("#.00"); // 创建一个数字格式化对象,用于格式化金额

        report.append("收支明细表\n");
        report.append("------------------------------\n");

        report.append("基本金: ").append(decimalFormat.format(baseAmount)).append(" 元\n");

        report.append("收入明细:\n");
        for (Income income : incomeList) {
            report.append("来源: ").append(income.getSource()).append("\n");
            report.append("金额: ").append(decimalFormat.format(income.getAmount())).append(" 元\n");
            report.append("--------------------\n");
        }

        report.append("支出明细:\n");
        for (Expense expense : expenseList) {
            report.append("类别: ").append(expense.getCategory()).append("\n");
            report.append("金额: ").append(decimalFormat.format(expense.getAmount())).append(" 元\n");
            report.append("--------------------\n");
        }

        JTextArea reportArea = new JTextArea(report.toString()); // 创建一个文本区域组件,用于显示报表内容
        reportArea.setFont(new Font("黑体", Font.PLAIN, 16)); // 设置文本区域的字体样式
        reportArea.setEditable(false); // 设置文本区域为只读
        reportArea.setLineWrap(true); // 设置文本自动换行
        reportArea.setWrapStyleWord(true); // 设置文本以单词为单位换行

        JScrollPane scrollPane = new JScrollPane(reportArea); // 创建一个带滚动条的面板,用于显示文本区域
        scrollPane.setPreferredSize(new Dimension(570, 350)); // 设置面板的首选大小

        JOptionPane.showMessageDialog(null, scrollPane, "收支明细", JOptionPane.PLAIN_MESSAGE);
        // 弹出一个对话框,显示收支明细报表
    }


    // 显示添加收入对话框的方法
    private void showIncomeDialog() {
        JTextField sourceField = new JTextField(10); // 创建一个文本框组件,用于输入收入来源
        JTextField amountField = new JTextField(10); // 创建一个文本框组件,用于输入收入金额

        JPanel panel = new JPanel(new GridLayout(2, 2)); // 创建一个面板,使用网格布局
        panel.add(new JLabel("收入来源:")); // 在面板中添加标签组件
        panel.add(sourceField); // 在面板中添加收入来源文本框
        panel.add(new JLabel("金额:")); // 在面板中添加标签组件
        panel.add(amountField); // 在面板中添加金额文本框

        int result = JOptionPane.showConfirmDialog(null, panel, "登记收入", JOptionPane.OK_CANCEL_OPTION);
        // 弹出一个对话框,显示收入对话框,并等待用户点击确认或取消按钮
        if (result == JOptionPane.OK_OPTION) { // 如果用户点击了确认按钮


            //情况判断再加一条,如果输入的并非字符串形式,那么无法录入。
            


            String source = sourceField.getText(); // 获取收入来源
            double amount = Double.parseDouble(amountField.getText()); // 获取收入金额

            baseAmount += amount; // 更新基本金额
            incomeList.add(new Income(source, amount)); // 将收入信息添加到收入列表

            JOptionPane.showMessageDialog(null, "收入已登记!", "提示", JOptionPane.INFORMATION_MESSAGE);
            // 弹出一个提示对话框,显示收入已登记的信息
        }
    }

    // 显示添加支出对话框的方法
    private void showExpenseDialog() {
        JTextField categoryField = new JTextField(10); // 创建一个文本框组件,用于输入支出类别
        JTextField amountField = new JTextField(10); // 创建一个文本框组件,用于输入支出金额

        JPanel panel = new JPanel(new GridLayout(2, 2)); // 创建一个面板,使用网格布局
        panel.add(new JLabel("支出类别:")); // 在面板中添加标签组件
        panel.add(categoryField); // 在面板中添加支出类别文本框
        panel.add(new JLabel("金额:")); // 在面板中添加标签组件
        panel.add(amountField); // 在面板中添加金额文本框

        int result = JOptionPane.showConfirmDialog(null, panel, "登记支出", JOptionPane.OK_CANCEL_OPTION);
        // 弹出一个对话框,显示支出对话框,并等待用户点击确认或取消按钮
        if (result == JOptionPane.OK_OPTION) { // 如果用户点击了确认按钮
            String category = categoryField.getText(); // 获取支出类别
            double amount = Double.parseDouble(amountField.getText()); // 获取支出金额

            if (amount <= baseAmount) { // 如果支出金额不超过基本金额
                baseAmount -= amount; // 更新基本金额
                expenseList.add(new Expense(category, amount)); // 将支出信息添加到支出列表

                JOptionPane.showMessageDialog(null, "支出已登记!", "提示", JOptionPane.INFORMATION_MESSAGE);
                // 弹出一个提示对话框,显示支出已登记的信息
            } else {
                JOptionPane.showMessageDialog(null, "基本金不足!", "错误", JOptionPane.ERROR_MESSAGE);
                // 弹出一个错误对话框,显示基本金不足的信息
            }
        }
    }

    // 清空收支记录的方法
    private void clearRecords() {
        int choice = JOptionPane.showConfirmDialog(null, "确认清空所有记录吗?", "提示", JOptionPane.YES_NO_OPTION);
        // 弹出一个确认对话框,等待用户点击是或否按钮
        if (choice == JOptionPane.YES_OPTION) { // 如果用户点击了是按钮
            baseAmount = 0.0; // 将基本金额设置为0
            incomeList.clear(); // 清空收入列表
            expenseList.clear(); // 清空支出列表

            JOptionPane.showMessageDialog(null, "记录已清空!", "提示", JOptionPane.INFORMATION_MESSAGE);
            // 弹出一个提示对话框,显示记录已清空的信息
        }
    }


    private class Income {
        private String source;
        private double amount;

        public Income(String source, double amount) {
            this.source = source;
            this.amount = amount;
        }

        public String getSource() {
            return source;
        }

        public double getAmount() {
            return amount;
        }
    }

    private class Expense {
        private String category;
        private double amount;

        public Expense(String category, double amount) {
            this.category = category;
            this.amount = amount;
        }

        public String getCategory() {
            return category;
        }

        public double getAmount() {
            return amount;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                FamilyAccountingSystem accountingSystem = new FamilyAccountingSystem();
                accountingSystem.setVisible(true);
            }
        });
    }
}

🐳七、总结

在设计上述代码的过程中,没有遇到太大的问题。这段代码是一个简单的家庭记账管理系统,使用Java Swing构建了一个图形用户界面。代码实现了添加收入、添加支出、显示收支明细和清空记录等功能。

设计过程中需要注意以下几点:

1.合理组织代码结构:将功能代码分散到不同的方法中,使得代码更加模块化和可维护。

2.合理使用面向对象的设计思想:将收入和支出抽象为类,使得代码更具可读性和扩展性。

3.注意异常处理:对用户的输入进行合法性验证,避免出现异常情况。

4.布局管理器的选择:根据需要使用适当的布局管理器,以实现界面的美观和灵活性。

通过完成这个项目,我对Java Swing的使用有了更深入的理解,并且学会了如何设计和实现一个简单的图形用户界面应用程序。我也意识到良好的代码结构和注释对于代码的可读性和可维护性是非常重要的。这个项目还启发了我对其他实际应用的开发和设计的思考,为我今后的学习和工作奠定了基础。

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

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

相关文章

【LeetCode】HOT 100(20)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

LeetCode·每日一题·2679. 矩阵中的和·排序

作者&#xff1a;小迅 链接&#xff1a;https://leetcode.cn/problems/sum-in-a-matrix/solutions/2330084/pai-xu-zhu-shi-chao-ji-xiang-xi-by-xun-g-a3gw/ 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;…

图书推荐管理系统Python,基于Django和协同过滤算法等实现

一、介绍 图书推荐系统 / 图书管理系统&#xff0c;以Python作为开发语言&#xff0c;基于Django实现&#xff0c;使用协同过滤算法实现对登录用户的图书推荐。 二、效果展示 三、演示视频 视频代码&#xff1a;https://www.yuque.com/ziwu/yygu3z/gq555ph49m9fvrze 四、Dj…

有什么事在Linux上顺理成章,在Windows就令人费解?

Linux与Windows都是十分常见的电脑操作系统&#xff0c;相信大家对它们二者都有所了解&#xff01;在我们的使用过程中&#xff0c;是否有遇到这种情况&#xff0c;在Linux上顺理成章&#xff0c;换到Windows上就令人费解&#xff1f; 文章目录 一、介绍2.1 Linux系统1.2 Wind…

第九十七天学习记录:Linux基础:实用操作Ⅱ

进程管理 进程 程序运行在操作系统中&#xff0c;是被操作系统所管理的。 为管理运行的程序&#xff0c;每一个程序在运行的时候&#xff0c;便被操作系统注册为系统中的一个&#xff1a;进程 并会为每一个进程都分配一个独有的&#xff1a;进程ID&#xff08;进程号&#xf…

机器人动力学与控制学习笔记(十六)——重复控制

十六、重复控制基本原理 16.1 重复控制理论 重复控制方法的目标是设计一个针对周期信号的跟踪控制器或者扰动补偿器&#xff0c;只需基于过去周期的误差信号&#xff0c;除了使用当前控制误差外&#xff0c;还“重复”使用了上一周期的误差&#xff0c;并与当前控制误差叠加在…

2023黑马头条.微服务项目.跟学笔记(三)

2023黑马头条.微服务项目.跟学笔记 三 自媒体文章发布1.自媒体前后端搭建1.1 后台搭建1.2 前台搭建 2.自媒体素材管理2.1 素材上传2.2.1 需求分析2.2.2 素材管理-图片上传-表结构2.2.3 实现思路2.2.4 接口定义2.2.5 自媒体微服务集成heima-file-starter2.2.6 具体实现 2.2 素材…

16 线程同步

文章目录 临界区MFC 临界区全部代码 事件内核对象信号量内核对象互斥量MFC 中设置只能有一个窗口 MFC线程通信 临界区 火车票买票问题 #include<stdio.h> #include <Windows.h>/* 临界区&#xff08;关键段&#xff09; */CRITICAL_SECTION g_cs;int g_count 500…

C++ day44

1、全局变量&#xff0c;int monster 10000;定义英雄类hero&#xff0c;受保护的属性string name&#xff0c;int hp,int attcKk;公有的无参构造&#xff0c;有参构造&#xff0c;虚成员函数void AtK()[blood-0,}&#xff0c;法师类继承自英雄类&#xff0c;私有属性int ap_at…

networkx

import networkx as nx import matplotlib.pyplot as plt# 创建一个空的无向图 G nx.Graph()# 添加节点 G.add_nodes_from([1, 2, 3, 4, 5])# 指定每个节点的位置 pos {1: (0, 0),2: (1, 1),3: (2, 0),4: (1, -1),5: (-1, -1)}# 添加边 G.add_edges_from([(1, 2), (1, 3), (1…

如何在家居行业运用IPD?

家居行业是我国国民经济重要的民生产业和具有显著国际竞争力的产业。家居家装是指对房屋的整体布局、风格、色彩及空间使用进行重新设定&#xff0c;整体的工程服务包含设计、建筑施工、建材生产、装饰及家具产品制造等&#xff0c;涉及装饰装修行业和制造业。家居家装行业内大…

【Redis三】主从复制、哨兵以及Cluster集群

主从复制、哨兵以及Cluster集群 1.Redis高可用2.Redis主从复制2.1 主从复制的作用2.2 主从复制流程 2.3 搭建Redis主从复制2.3.1 安装部署Redis2.3.2 验证主从复制结果 3.Redis哨兵模式3.1 哨兵模式概述3.2 哨兵模式的作用3.3 故障转移机制3.4 主节点的选举3.5 搭建Redis哨兵模…

布尔运算-基于CGAL的布尔运算

前言&#xff1a;vtk提供的布尔运算接口vtkBooleanOperationFilter或是其他的接口&#xff0c;都存在运行不稳定且速度慢的情况&#xff1b;本博文主要使用CGAL库对布尔运算进行优化&#xff0c;希望给各位小伙伴有所帮助&#xff01; CAGL开源库 介绍 CGAL 是一个软件项目&a…

云原生之深入解析Docker容器的网络及其配置

一、Docker 容器网络 Docker 在安装后自动提供 3 种网络&#xff0c;可以使用 docker network ls 命令查看&#xff1a; [rootlocalhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE cd97bb997b84 bridge …

图像的基础操作

1.获取并修改图像中的像素值 img np.zeros((256, 256, 3), np.uint8) # 创建图像px img[100, 100] # 获取&#xff08;100&#xff0c;100&#xff09;点的像素值 blue img[100, 100, 0] # 仅获取&#xff08;100&#xff0c;100&#xff09;蓝色通道的像素值 …

图像的几何变换

1.图像的缩放 用途&#xff1a;对图像的大小尺寸进行调整&#xff0c;使图像放大或缩小。 代码&#xff1a; import cv2 as cvimg cv.imread(img.jpg)rows, cols img.shape[:2]# 使用绝对坐标 res cv.resize(img, (2 * cols, 2 * rows), interpolationcv.INTER_CUBIC)# 使…

面对“神奇的甲方”:如何应对匪夷所思的需求

在工作中&#xff0c;我们常常会遇到一些“神奇的甲方”&#xff0c;他们总是能给我们带来匪夷所思甚至无厘头的需求。本文将分享作者的经历&#xff0c;并提供一些建议&#xff0c;帮助读者应对这些“无理的需求”。 文章目录 方向一&#xff1a;分享那些你遇到的无理需求方向…

音轨分离 spleeter

https://www.cnblogs.com/ytxwzqin/p/12673661.htmlhttps://www.cnblogs.com/ytxwzqin/p/12673661.html伴奏提取福音&#xff0c;人声分离框架Spleeter1、引言对于制作人、DJ以及任何想分离音频进行单独演奏的人来说&#xff0c;将已经混音后的歌曲拆分为人声和伴奏一直是较为h…

Dirichlet Process 1

如下图的一个简单样本&#xff0c;如果我们不知道图中的样本是出自几个高斯分布&#xff0c;那我们如果求这个图中的样本应该归属于几个高斯分布那&#xff1f;直观看上去&#xff0c;有同学可能说是4个&#xff0c;有同学可能说是2个&#xff0c;然而如果是高维数据那&#xf…

2023年艺术品和古董行业研究报告

第一章 行业概况 艺术品通常指的是创造出来为了表达审美、情感或思想的物品&#xff0c;如绘画、雕塑、照片、装置艺术等。艺术品的价值常常来自于它的创新性、技术精湛以及艺术表达的深度和力度。此外&#xff0c;艺术家的名气和作品的历史背景也会影响其价值。 古董则通常指…