【Java篇】一气化三清:类的实例化与封装的智慧之道

news2025/3/20 15:08:45

文章目录

  • 类和对象(中)
    • 五、对象的构造及初始化
      • 5.1 如何初始化对象
      • 5.2 构造方法
        • 5.2.1 构造方法的概念
        • 5.2.2 构造方法的特性
      • 5.3 默认初始化
      • 5.4 就地初始化
    • 六、封装
      • 6.1 封装的概念
      • 6.2 访问限定符
      • 6.3 封装扩展之包
        • 6.3.1 包的概念
        • 6.3.3导入包
        • 6.3.3全类名
        • 6.3.4 静态导入
        • 6.3.5 IDE工具中的包结构
        • 6.3.6 包的访问权限控制举例
      • 6.3.7 常见的包
    • 七、总结与展望
      • 7.1 总结
      • 7.2 总结

类和对象(中)

💬 欢迎讨论:如果你对本篇内容有任何疑问或想深入探讨,欢迎在评论区留言交流!

👍 点赞、收藏与分享:觉得内容有帮助就请点赞、收藏并分享给更多学习Java的小伙伴!

🚀 继续学习之旅:本篇文章将详细讲解对象的构造与初始化、封装、static成员、代码块以及内部类等高级内容,让你进一步掌握面向对象编程的精髓。


五、对象的构造及初始化

5.1 如何初始化对象

通过前面知识点的学习我们知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。

public static void main(String[] args) {
	int a;
	System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a

要让上述代码通过编译,非常简单,只需在正式使用变量之前给它设置初始值即可。

public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(2021,6,9);
    d.printDate();
}
// 代码可以正常通过编译

如果是对象,就需要调用之前写的 setDate 方法将具体的日期设置到对象中。

通过上述例子我们发现两个问题:

  • 问题1:每次对象创建好后调用 setDate 方法设置具体日期显得比较麻烦,那么对象该如何初始化?
  • 问题2:局部变量必须初始化才能使用,而字段声明之后没有给值依然可以使用,这是因为字段具有默认初始值。

为了解决问题1,Java引入了 构造方法,使得对象在创建时就能完成初始化操作。


5.2 构造方法

构造方法(也称为构造器)是一种特殊的成员方法,其主要作用是初始化对象。

5.2.1 构造方法的概念
public class Date {
    public int year;
    public int month;
    public int day;
    // 构造方法:
    // 名字与类名相同,没有返回值类型,设置为void也不行
    // 一般情况下使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)方法被调用了");
    }
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }
    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
        d.printDate(); // 2021-6-9
    }
}

构造方法的特点是:

  • 名字必须与类名相同,且没有返回值类型(连void都不行)。
  • 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次。
    注意:构造方法的作用是对对象中的成员进行初始化,并不负责给对象开辟内存空间。
5.2.2 构造方法的特性

构造方法具有如下特性:

  1. 名字必须与类名完全相同
  2. 没有返回值类型,即使设置为void也不行
  3. 创建对象时由编译器自动调用,且在对象生命周期内只调用一次(就像人的出生,每个人只能出生一次)
  4. 支持重载:同一个类中可以定义多个构造方法,只要参数列表不同即可

示例代码1:带参构造方法

public class Date {
    public int year;
    public int month;
    public int day;
    
    // 构造方法:名字与类名相同,没有返回值类型,使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int, int, int)方法被调用了");
    }
    
    public void printDate() {
        System.out.println(year + "-" + month + "-" + day);
    }
    
    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021, 6, 9); // 输出:Date(int, int, int)方法被调用了
        d.printDate();                // 输出:2021-6-9
    }
}

示例代码2:无参构造方法

public class Date {
    public int year;
    public int month;
    public int day;
    
    // 无参构造方法:给成员变量设置默认初始值
    public Date() {
        this.year = 1900;
        this.month = 1;
        this.day = 1;
    }
}

上述两个构造方法名字相同但参数列表不同,构成了方法的重载。

  1. 如果用户没有显式定义构造方法,编译器会生成一个默认的无参构造方法。

注意:一旦用户显式定义了构造方法,编译器就不会再生成默认构造方法了

示例代码3:仅定义带参构造方法时默认构造方法不会生成

// 带有三个参数的构造方法
public Date(int year, int month, int day) {
    this.year = year;
    this.month = month;
    this.day = day;
}

public void printDate(){
    System.out.println(year + "-" + month + "-" + day);
}

public static void main(String[] args) {
    Date d = new Date(); // 编译期报错,因为没有无参构造方法
    d.printDate();
}

示例代码4:只有无参构造方法的情况

public class Date {
    public int year;
    public int month;
    public int day;
    
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }
    
    public static void main(String[] args) {
        Date d = new Date();
        d.printDate();
    }
}

示例代码5:只有带参构造方法的情况

public class Date {
    public int year;
    public int month;
    public int day;
    
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}
  1. 构造方法中可以通过 this(…) 调用其他构造方法来简化代码。
    注意:this(…) 必须是构造方法中的第一条语句,否则编译器会报错。

示例代码6:正确使用this(…)实现构造器链

public class Date {
    public int year;
    public int month;
    public int day;
    
    // 无参构造方法 -- 内部调用带参构造方法实现初始化
    // 注意:this(1900, 1, 1);必须是构造方法中的第一条语句
    public Date(){
        // System.out.println(year); // 若取消注释则编译会失败
        this(1900, 1, 1);
        // 以下赋值代码被省略,因为已在带参构造方法中完成初始化
        // this.year = 1900;
        // this.month = 1;
        // this.day = 1;
    }
    
    // 带有三个参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

注意:构造方法中的 this(…) 调用不能形成循环,否则会导致编译错误。

public Date(){
	this(1900,1,1);
}

public Date(int year, int month, int day) {
	this();
}
/*
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用
*/
  1. 在大多数情况下,我们使用 public 来修饰构造方法,但在特殊场景下(如实现单例模式)可能会使用 private 修饰构造方法。

5.3 默认初始化

在上文中提到的第二个问题:为什么局部变量在使用前必须初始化,而成员变量可以不初始化?

要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:

Date d = new Date(2021,6,9);

在程序员看来只是一句简单的语句,但 JVM 层面需要做好多事情。下面简单介绍下:

  1. 检测对象对应的类是否被加载,如果没有则加载
  2. 为对象分配内存空间并先默认初始化
  3. 处理并执行类中的 init 方法
  4. 初始化分配好的空间 (说明:多个线程同时申请资源,JVM 要保证分配给对象的空间内干净。)

即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:Java中的 成员变量 会由 JVM 自动赋予默认值(如int类型为0,boolean类型为false等),而局部变量则需要显式初始化才能使用。

Java为不同的数据类型提供了默认值,具体如下所示:

数据类型默认值
byte0
char‘\u0000’
short0
int0
long0L
booleanfalse
float0.0f
double0.0d
referencenull

这些默认值确保了即使对象的成员变量没有显式初始化,也不会发生错误,成员变量会有一个初始的稳定状态。

  1. 设置对象头信息(关于对象内存模型后面会介绍)

  2. 调用构造方法,给对象中各个成员赋值


5.4 就地初始化

就地初始化是指在成员变量声明时直接为它们赋初值。这种方法在代码的简洁性上具有优势,可以避免每次创建对象时重复设置成员变量的值。

代码示例:

public class Date {
    public int year = 1900;  // 就地初始化
    public int month = 1;    // 就地初始化
    public int day = 1;      // 就地初始化

    public Date() {
        // 构造方法在此处不需要再次初始化year、month、day,它们已经有默认值
    }
    
    public void printDate() {
        System.out.println(year + "-" + month + "-" + day);
    }

    public static void main(String[] args) {
        Date d = new Date();
        d.printDate();  // 输出:1900-1-1
    }
}

在这个例子中,yearmonthday 的值在声明时就被初始化为1900、1和1,确保了每次创建对象时这些值已经存在。


六、封装

6.1 封装的概念

封装是面向对象编程的三大特性之一,其核心思想是将数据和操作数据的方法结合在一起,并对外隐藏实现细节。
例如,电脑作为一个复杂的设备,用户只需通过开关、键盘和鼠标等接口进行交互,而不必关心内部CPU、显卡等工作原理。

在这里插入图片描述

简单来说就是套壳屏蔽细节。


6.2 访问限定符

访问修饰符说明

  • public:可以理解为一个人的外部接口,能被外部访问。
  • protected:主要是给继承使用,子类继承后就能访问到。
  • default(不写修饰符时即为默认访问修饰符):对于同一包内的类可见,不同包则不可见。
  • private:只能在当前类中访问。

(这部分要介绍完继承后才能完全理解)
在这里插入图片描述

【说明】protected 主要是给继承使用;default 只能给同一个包内使用;按照自己的理解去记忆。


示例代码:

public class Computer {
    private String cpu;
    private String brand;
    private String memory;
    private String screen;

    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }

    public void boot() {
        System.out.println("开机");
    }

    public void shutDown() {
        System.out.println("关机");
    }
}
public class TestComputer {
    public static void main(String[] args) {
        Computer c = new Computer("华为", "i9", "16G", "4K");
        c.boot();
        c.shutDown();
    }
}

注意:一般情况下,成员变量通常设置为 private,成员方法设置为 public


6.3 封装扩展之包

6.3.1 包的概念

包(Package)用于对类进行分组管理,有助于解决类名冲突并提高代码的组织性。例如,将相似功能的类归为同一包。

为了更好的管理类,把多个类收集在一起成为一组,称为软件包
在这里插入图片描述

6.3.3导入包

在Java中,如果我们需要使用不在默认 java.lang 包中的类或接口,就需要使用 import 关键字来导入。
例如,我们想使用 java.util.Date 这个类,就可以这样做:

import java.util.Date;

public class TestImport {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);
    }
}

这样就可以正常创建 Date 对象并使用。


6.3.3全类名

当不同包中存在同名的类时(如 java.util.Datejava.sql.Date 都叫 Date),可能会引发冲突。
这时,可以使用 全类名(Fully Qualified Name)来指定使用哪个类:

public class TestFullName {
    public static void main(String[] args) {
        // 使用全类名来区分两个Date类
        java.util.Date d1 = new java.util.Date();
        java.sql.Date d2 = new java.sql.Date(System.currentTimeMillis());
        
        System.out.println(d1);
        System.out.println(d2);
    }
}

通过在创建对象时加上包名,就可以区分来自 java.utiljava.sqlDate 类。


6.3.4 静态导入

从 Java 5 开始,支持使用 静态导入import static)的方式将某个类中的 静态成员(常量或方法) 导入到当前类中,从而在调用时可以省略类名。

示例代码:

import static java.lang.Math.PI;
import static java.lang.Math.random;

public class TestStaticImport {
    public static void main(String[] args) {
        System.out.println(PI);      // 直接使用PI常量
        System.out.println(random()); // 直接使用random()方法
    }
}

如果不使用静态导入,则需要写成:

System.out.println(Math.PI);
System.out.println(Math.random());

6.3.5 IDE工具中的包结构

当我们使用 IntelliJ IDEA 或 Eclipse 等 IDE 工具时,会在项目结构中直观地看到包名与文件夹一一对应。

  • 包名一般使用 小写 的域名反写形式(如 com.example.project),在 IDE 中会对应层级文件夹结构。
  • 在同一个包下,可以放置多个类文件,便于组织与管理。

在实际开发中,合理划分包结构能让项目更易于维护和理解。


6.3.6 包的访问权限控制举例

Computer类位于com.bit.demo1包中,TestComputer位于com.bit.demo2包中:

package com.bit.demo1;

public class Computer {
    private String cpu;        // cpu
    private String memory;     // 内存
    public String screen;      // 屏幕
    String brand;              // 品牌

    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }

    public void PowerOff(){
        System.out.println("关机~~~");
    }

    public void SurfInternet(){
        System.out.println("上网~~~");
    }
}

package com.bit.demo2;

import com.bit.demo1.Computer;

public class TestComputer {
    public static void main(String[] args) {
        Computer p = new Computer("HW", "i7", "8G", "13*14");

        System.out.println(p.screen);   // 公有属性,可以被其他包访问
        // System.out.println(p.cpu);    // 私有属性,不能被其他包访问
        // System.out.println(p.brand);  // brand是default,不允许被其他包中的类访问
    }
}

注意:
如果去掉前面的Computer类中的public修饰符,代码也会编译失败。


6.3.7 常见的包

  1. java.lang:系统常用基础类(String,Object),此包从JDK1.1后自动导入。
  2. java.lang.reflect:Java反射机制包;
  3. java.net:进行网络编程开发包;
  4. java.sql:进行数据库开发的包;
  5. javax.util:Java提供的工具程序包(集合类等)非常重要;
  6. javalio.io:编程程序包。

注意事项: import 和 C++ 的 #include 差别很大. C++ 必须 #include 来引入其他文件内容, 但是 Java 不需要.import 只是为了写代码的时候更方便.

区别如下:

  • Java 的 import
    仅在编译时为你提供类或接口的简写路径,使你可以直接使用类名而不用写出完整的包名。实际上,编译器会在编译过程中通过类路径(classpath)去查找相应的类文件,而不会把代码插入到当前文件中。

  • C/C++ 的 #include
    预处理器会在编译之前将头文件的内容直接拷贝进源代码文件中,这种方式实际上是将文件的内容“粘贴”到包含它的文件里。

因此,Java 的 import 只是一种简化引用的机制,并不涉及代码的复制。


七、总结与展望

在本篇文章中,我们围绕对象的构造与初始化、封装、包的管理以及访问权限等内容展开了详细讲解,帮助大家深入理解Java面向对象编程的核心概念。

7.1 总结

  • 对象的构造与初始化

    • 构造方法:通过构造方法,我们可以在创建对象时立即为其成员赋值,保证对象在使用前处于有效状态。
    • 构造器重载与this调用:支持多个构造方法以及构造器链,让对象初始化更加灵活和简洁。
    • 默认初始化与就地初始化:成员变量会自动获得默认值,同时也可以在声明时直接赋值,避免重复代码。
  • 封装

    • 核心思想:将数据与操作数据的方法绑定在一起,通过访问限定符(public、private、protected、default)隐藏内部实现细节。
    • 访问控制:合理使用访问修饰符保护数据安全,提供公开接口供外部使用,增强了程序的健壮性和安全性。
  • 包的管理与导入

    • 包的概念:通过将相关类归为一组,实现代码的模块化管理和命名空间隔离,避免类名冲突。
    • import语句:在编译时提供类名简写路径,与C/C++的#include机制不同,import不进行代码复制,仅起到标识和简化引用的作用。

7.2 总结

  • 深入static成员
    在后续的内容中,我们将更详细地探讨static关键字的使用,包括静态变量、静态方法及其在类中的意义,帮助大家更好地理解类级别的共享特性。

  • 代码块与初始化块
    将介绍类中的初始化块和静态代码块,讨论它们在对象创建过程中的执行顺序和作用,为进一步掌握对象生命周期奠定基础。

  • 内部类与匿名类
    内部类是一种特殊的类定义方式,它能够更紧密地绑定外部类的成员,将在未来篇章中深入剖析其用法和设计思想。

  • 面向对象的设计原则
    随着对类和对象理解的深入,我们也将探讨更多面向对象设计的原则和模式,帮助大家构建更健壮、可维护的Java应用程序。

本篇文章为大家构建了坚实的面向对象编程基础,希望通过系统的总结和展望,能够激发你对Java编程更深层次的兴趣。欢迎在评论区分享你的见解或提问,共同进步!


以上就是关于【Java篇】一气化三清:类的实例化与封装的智慧之道内存中的桥梁:Java数组与引用的灵动操作内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️
在这里插入图片描述

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

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

相关文章

VMware上调整centos终端的背景颜色

目录 1. 正常打开一个终端,背景颜色默认为白色 2. 在打开的终端页面上右击,选择“配置文件首选项” 3. 取消默认勾选的 “使用系统主题中的颜色” 即可 1. 正常打开一个终端,背景颜色默认为白色 2. 在打开的终端页面上右击,选择…

Latex2024安装教程(附安装包)Latex2024详细图文安装教程

文章目录 前言一、Latex2024下载二、Texlive 2024安装教程1.准备安装文件2.启动安装程序3.配置安装选项4.开始安装5.安装完成6.TeX Live 2024 安装后确认 三、Texstudio 安装教程1.准备 Texstudio 安装2.启动 Texstudio 安装向导3.选择安装位置4.等待安装完成5.启动 Texstudio6…

用了Cline和华为云的大模型,再也回不去了

这两年AI火热,受影响最大的还是程序员群体,因为编程语言是高度形式化的,完全可以用BNF等形式精确地定义,不像自然语言那样,容易出现歧义。另外开源是软件界的潮流,GitHub上有海量的开源代码可供AI来训练&am…

详细解析格式化消息框的代码

书籍:《windows程序设计(第五版)》的开始 环境:visual studio 2022 内容:格式化消息框 说明:以下内容大部分来自腾讯元宝。 封装MessageBoxPrintf 在MessageBoxPrintf()中处理可变参数,通过va_list机制&#xff0c…

Jetson Nano 三个版本(B01 4GB、Orin 4GB、Orin 8GB)本地部署Deepseek等大模型的测评

Jetson Nano三个版本(B01 GB、Orin 4GB、Orin 8GB)本地部署Deepseek等大模型的测评 一、为什么要在终端设备部署大模型?二、 Jetson Nano推理大模型时计算资源占用情况分析为什么测试Jetson Nano?三款Jetson Nano芯片简介 三、大模型推理实验…

mac calDAV 日历交互

安装Bakal docker https://sabre.io/dav/building-a-caldav-client/ 在Bakal服务器上注册账户 http://localhost:8080/admin/?/users/calendars/user/1/ 在日历端登录账户: Server: http://127.0.0.1:8080/dav.php Server Path: /dav.php/principals/lion No e…

数据库监控:确保业务连续性和用户体验

在数字化时代,数据库作为企业的数据心脏,其重要性不言而喻。无论是交易系统、客户关系管理系统,还是数据分析平台,都离不开数据库的支撑。然而,数据库的运行状态和性能直接影响着企业的业务连续性和用户体验。因此&…

PointVLA:将 3D 世界注入视觉-语言-动作模型

25年3月来自美的集团、上海大学和华东师大的论文“PointVLA: Injecting the 3D World into Vision-Language-Action Models”。 视觉-语言-动作 (VLA) 模型利用大规模 2D 视觉语言预训练,在机器人任务方面表现出色,但它们对 RGB 图像的依赖,…

SpringBoot-MVC配置类与 Controller 的扫描

文章目录 前言一、自动配置类位置二、自动配置类解析2.1 WebMvcAutoConfiguration2.1.1 EnableWebMvcConfiguration 2.2 DispatcherServletAutoConfiguration 三、RequestMapping 的扫描过程3.1 RequestMappingHandlerMapping#afterPropertiesSet3.2 RequestMappingHandlerMapp…

企业年度经营计划制定与管理方法论(124页PPT)(文末有下载方式)

资料解读:企业年度经营计划制定与管理方法论 详细资料请看本解读文章的最后内容。 在企业的发展进程中,年度经营计划的制定与管理至关重要,它犹如企业前行的导航图,指引着企业在复杂多变的市场环境中稳健发展。这份《企业年度经营…

基于微信小程序的充电桩管理系统

一、开发背景 在开发充电汽车管理系统之前,深入的需求分析至关重要。我们要充分了解不同用户群体的需求,比如私家车主希望充电过程便捷、高效、安全,能够实时查看充电状态和费用明细;出租车、网约车司机则更注重充电速度和充电桩…

算法模型从入门到起飞系列——递归(探索自我重复的奇妙之旅)

文章目录 前言一、递归本质1.1 递归的要素1.2 递归特点 二、递归&迭代2.1 递归&迭代比较2.2 递归&迭代如何实现相同功能2.2.1 递归实现2.2.2 迭代实现2.2.3 性能对比 三、优雅的递归理解3.1 阶乘计算分解3.2 [DFS](https://blog.csdn.net/qq_38315952/article/deta…

YOLO+OpenCV强强联手:高精度跌倒检测技术实战解析

目录 关于摔倒检测 摔倒检测核心逻辑 摔倒检测:联合多种逻辑判断 原理详细解释 1. 导入必要的库 2. 定义函数和关键点连接关系 3. 筛选有效关键点并计算边界框 4. 计算人体上下半身中心点和角度 5. 绘制关键点和连接线 6. 绘制角度标注和检测跌倒 7. 返回处理后的图…

麒麟银河V10服务器RabbitMQ安装

安装步骤 rabbitMQ依赖于erlang的环境,所以需要先安装erlang,erlang跟rabbitMQ是有版本之间的关联关系的,根据对应的版本去安装下载,保证少出问题。 可以通过官网来查看RabbitMQ和erlang之间的版本对应关系 rabbitMQ和erlang之间…

extern和static的作用(有例子)

一、extern extern的作用 声明而非定义 extern告诉编译器某个变量或函数存在于其他地方(通常是另一个源文件),当前只是声明它,而不是定义它(分配内存)。定义只能在一个地方出现,而声明可以多次…

【8】分块学习笔记

前言 分块是一种重要的高级数据结构思想,核心为大段维护,局部朴素。 顺带一提,由于个人技术水平,本篇博客的难度并没有标题所述的 8 8 8 级。分块还是很难的。 分块 分块,是“优雅的暴力”。 分块的基本思想是把数据分为若干…

【蓝桥杯】省赛:分糖果(思维/模拟)

思路 数据很小,直接暴力模拟。 有意思的是一个列表如何当成循环队列写?可以arr[(i1)%n]让他右边超出时自动回到开头。 code import os import sysn int(input()) arr list(map(int,input().split()))ans 0 while 1:arr1 arr.copy()for i in range…

进程间通信(1)——管道

1. 进程间通信简介 进程间通信(Inter-Process Communication,IPC)是指不同进程之间交换数据的机制。由于进程具有独立的地址空间,它们无法直接访问彼此的数据,因此需要IPC机制来实现信息共享、数据传递或同步操作。 …

【正点原子K210连载】第七十六章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第七十六章 音频FFT实验 本章将介绍CanMV下FFT的应用,通过将时域采集到的音频数据通过FFT为频域。通过本章的学习,读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节: 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…

【杂记二】git, github, vscode等

一、前言 暂时空着... 二、git 2.1 可能的疑问 1. VSCode 项目名和 GitHub 仓库名是否需要一致? 不需要一致。 VSCode 项目名(也就是你本地的文件夹名字)和 GitHub 仓库名可以不一样。 Git 是一个分布式版本控制系统,它主要关…