当前位置: 首页 > news >正文

Java 面向对象-上

第一章.面向对象基础

1.1 面向对象的介绍

1.面向对象是一种编程思想,Java 的核心思想就是面向对象。 2.面向对象关注的是: 谁来做这件事 这个对象有什么数据 这个对象能完成什么行为 3.面向对象的好处: a.把数据和行为放到同一个类中,结构更清晰 b.可以复用已经写好的类和对象 c.后期维护时,可以围绕某一类事物单独修改 4.面向对象三大特征: 封装 继承 多态 5.现阶段常见使用方式: a.创建对象后调用成员: 类名 对象名 = new 类名(); 对象名.成员名 b.调用静态成员: 类名.静态成员名

1.2 类和对象

1.类: 对一类事物的抽象描述。 例如:学生类、手机类、账户类。 2.对象: 类的具体存在。 例如:张三这个学生、我的手机、某一个账户。 3.类和对象的关系: 类是对象的设计图。 对象是根据类创建出来的具体实例。
概念说明示例
一类事物的抽象描述Student、Phone、Account
对象某个具体事物stu、phone、account
成员变量对象有什么数据name、age、price
成员方法对象能做什么study()、call()、deposit()

1.3 类的组成

1.成员变量: 定义在类中方法外。 用来描述这一类事物有什么数据。 2.成员方法: 定义在类中。 用来描述这一类事物能做什么。 3.测试类: 带 main 方法的类,用于运行程序。 4.实体类: 用来描述一类事物的类。
public class Student { String name; int age; public void study() { System.out.println(name + "正在学习 Java"); } }
public class Demo01Student { public static void main(String[] args) { Student stu = new Student(); stu.name = "林晓"; stu.age = 18; System.out.println(stu.name); // 林晓 System.out.println(stu.age); // 18 stu.study(); // 林晓正在学习 Java } }

注意:

1.一个 Java 文件中可以写多个类,但是 public 修饰的类只能有一个。 2.public 修饰的类名必须和文件名保持一致。 3.现阶段实体类一般不写 main 方法,测试类中写 main 方法。

第二章.对象的使用

2.1 创建对象并调用成员

1.创建对象: 类名 对象名 = new 类名(); 2.调用成员变量: 对象名.成员变量名 3.调用成员方法: 对象名.成员方法名()
public class Phone { String brand; double price; public void call(String name) { System.out.println("正在给" + name + "打电话"); } public void showInfo() { System.out.println(brand + "," + price); } }
public class Demo02Phone { public static void main(String[] args) { Phone phone = new Phone(); phone.brand = "华为"; phone.price = 4999.0; phone.showInfo(); // 华为,4999.0 phone.call("李明"); // 正在给李明打电话 } }

2.2 对象作为引用类型

1.类本身也是一种引用类型。 2.对象变量中保存的不是对象本身,而是对象在堆内存中的地址值。 3.多个变量指向同一个对象时,通过任意一个变量修改对象内容, 其他变量再次访问时也能看到修改后的结果。
public class Demo03Reference { public static void main(String[] args) { Student s1 = new Student(); s1.name = "周宁"; s1.age = 19; Student s2 = s1; s2.age = 20; System.out.println(s1.age); // 20 System.out.println(s2.age); // 20 } }

2.3 匿名对象

1.匿名对象: 没有对象名的对象。 2.格式: new 类名().成员名 3.适合场景: 只需要临时调用一次方法时,可以使用匿名对象。 4.不适合场景: 如果需要多次使用同一个对象的数据,不要使用匿名对象。
public class Demo04Anonymous { public static void main(String[] args) { new Phone().call("王强"); Phone phone = new Phone(); phone.brand = "小米"; phone.price = 2999.0; phone.showInfo(); } }

注意:

1.new Phone().brand = "小米"; new Phone().showInfo(); 上面两行代码创建的是两个不同对象, 第一行赋值不会影响第二行创建的新对象。 2.涉及赋值、取值、重复使用时,优先使用有名字的对象。

第三章.成员变量和局部变量

3.1 成员变量和局部变量区别

区别成员变量局部变量
定义位置类中方法外方法内或形参位置
默认值有默认值没有默认值,必须先赋值再使用
作用范围整个对象内部所在方法或代码块内部
内存位置堆内存栈内存
生命周期随对象创建而创建,随对象消失而消失随方法调用而创建,随方法结束而消失
public class Account { String owner; double balance; public void save(double money) { double afterSave = balance + money; balance = afterSave; } }
public class Demo05Variable { public static void main(String[] args) { Account account = new Account(); System.out.println(account.owner); // null System.out.println(account.balance); // 0.0 account.owner = "陈一"; account.save(500.0); System.out.println(account.balance); // 500.0 } }

注意:

1.owner 和 balance 是成员变量,有默认值。 2.money 和 afterSave 是局部变量,只能在 save 方法中使用。 3.局部变量没有默认值,使用前必须手动赋值。

第四章.封装

4.1 封装的介绍

1.封装: 隐藏对象内部实现细节,只对外提供必要的公共访问方式。 2.封装的常见体现: a.把一段功能代码放到方法中 b.使用 private 修饰成员变量 c.通过 public 的 get/set 方法间接访问成员变量 3.private: 私有访问权限。 被 private 修饰的成员只能在本类中直接访问。 4.公共访问方法: setXxx():给成员变量赋值 getXxx():获取成员变量的值

4.2 private 和 get/set 方法

public class User { private String username; private int age; public void setUsername(String username) { this.username = username; } public String getUsername() { return username; } public void setAge(int age) { if (age < 0 || age > 120) { System.out.println("年龄不合法"); return; } this.age = age; } public int getAge() { return age; } }
public class Demo06Private { public static void main(String[] args) { User user = new User(); user.setUsername("赵敏"); user.setAge(20); System.out.println(user.getUsername()); // 赵敏 System.out.println(user.getAge()); // 20 user.setAge(-1); // 年龄不合法 System.out.println(user.getAge()); // 20 } }

注意:

1.成员变量私有化之后,外部不能直接使用 对象名.成员变量名 访问。 2.get/set 方法可以在赋值和取值时加入校验逻辑。 3.如果属性没有私有化,也可以写 get/set 方法,但是封装意义不强。

4.3 this 关键字

1.this: 代表当前对象。 2.当前对象: 哪个对象调用 this 所在的方法,this 就代表哪个对象。 3.this 的常见作用: 区分重名的成员变量和局部变量。 4.就近原则: 如果成员变量和局部变量重名,直接写变量名时优先使用局部变量。 想访问成员变量时,使用 this.成员变量名。
public class Book { private String title; private double price; public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } public void setPrice(double price) { this.price = price; } public double getPrice() { return price; } public void printInfo() { System.out.println(this.title + "," + this.price); } }
public class Demo07This { public static void main(String[] args) { Book book = new Book(); book.setTitle("Java 入门"); book.setPrice(59.9); book.printInfo(); // Java 入门,59.9 } }

第五章.构造方法

5.1 构造方法概述

1.构造方法也叫构造器。 2.作用: 创建对象。 可以在创建对象的同时给成员变量赋值。 3.特点: a.方法名必须和类名完全一致 b.没有返回值类型,连 void 都不能写 c.new 对象时会自动调用构造方法

5.2 空参构造

1.格式: public 类名() { } 2.特点: 如果一个类中没有写任何构造方法,JVM 会默认提供一个空参构造。 3.注意: 只要手动写了任意构造方法,JVM 就不会再提供默认空参构造。
public class Cat { private String name; private int age; public Cat() { } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } }
public class Demo08Constructor { public static void main(String[] args) { Cat cat = new Cat(); cat.setName("团团"); cat.setAge(2); System.out.println(cat.getName() + "," + cat.getAge()); // 团团,2 } }

5.3 有参构造

1.格式: public 类名(形参列表) { 给成员变量赋值; } 2.作用: 创建对象时直接完成属性赋值。 3.建议: 实体类中一般同时写空参构造和有参构造。
public class Cat { private String name; private int age; public Cat() { } public Cat(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public class Demo09Constructor { public static void main(String[] args) { Cat c1 = new Cat(); c1.setName("小白"); c1.setAge(1); Cat c2 = new Cat("橘子", 3); System.out.println(c1.getName() + "," + c1.getAge()); // 小白,1 System.out.println(c2.getName() + "," + c2.getAge()); // 橘子,3 } }

第六章.标准 JavaBean

6.1 JavaBean 规范

1.JavaBean 是 Java 中编写实体类的一种常见规范。 2.标准 JavaBean 通常要求: a.类使用 public 修饰 b.成员变量使用 private 修饰 c.提供 public 的空参构造 d.提供带全部参数的构造方法 e.提供每个成员变量对应的 get/set 方法 3.快捷生成方式: IntelliJ IDEA 中可以使用 Alt + Insert 部分电脑需要使用 Alt + Fn + Insert

6.2 JavaBean 示例

public class Product { private int id; private String name; private double price; public Product() { } public Product(int id, String name, double price) { this.id = id; this.name = name; this.price = price; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }
public class Demo10JavaBean { public static void main(String[] args) { Product p1 = new Product(); p1.setId(1); p1.setName("键盘"); p1.setPrice(199.0); Product p2 = new Product(2, "鼠标", 99.0); System.out.println(p1.getName() + "," + p1.getPrice()); // 键盘,199.0 System.out.println(p2.getName() + "," + p2.getPrice()); // 鼠标,99.0 } }

6.3 JavaBean 和表的对应关系

1.实际开发中,JavaBean 常用来封装数据。 2.JavaBean 和数据库表的常见对应关系: 表名 -> 类名 列名 -> 成员变量名 列的数据类型 -> 成员变量的数据类型 每一行数据 -> 一个 JavaBean 对象
数据库表 userJavaBean
idprivate int id;
usernameprivate String username;
passwordprivate String password;
ageprivate int age;
public class UserInfo { private int id; private String username; private String password; private int age; public UserInfo() { } public UserInfo(int id, String username, String password, int age) { this.id = id; this.username = username; this.password = password; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

第七章.static 关键字

7.1 static 的介绍

1.static 是静态关键字。 2.static 可以修饰: 成员变量 成员方法 3.静态成员的特点: a.属于类,不属于某一个对象 b.随着类的加载而加载 c.优先于对象存在 d.同一个类创建出的所有对象共享同一份静态成员 4.调用方式: 类名.静态成员名

7.2 static 成员变量

public class Employee { String name; int age; static String company = "星河科技"; }
public class Demo11StaticVariable { public static void main(String[] args) { Employee e1 = new Employee(); e1.name = "许晨"; e1.age = 25; Employee e2 = new Employee(); e2.name = "沈月"; e2.age = 24; System.out.println(Employee.company); // 星河科技 Employee.company = "云舟科技"; System.out.println(Employee.company); // 云舟科技 System.out.println(e1.company); // 云舟科技 System.out.println(e2.company); // 云舟科技 } }

注意:

1.静态成员建议使用 类名.静态成员名 调用。 2.虽然对象也能调用静态成员,但是不推荐,容易误解为这个成员属于对象。

7.3 static 成员方法

public class MathTools { public static int getMax(int a, int b) { return a > b ? a : b; } public static boolean isEven(int num) { return num % 2 == 0; } }
public class Demo12StaticMethod { public static void main(String[] args) { System.out.println(MathTools.getMax(10, 20)); // 20 System.out.println(MathTools.isEven(8)); // true } }

7.4 static 访问特点

1.静态方法中: 可以直接访问静态成员。 不能直接访问非静态成员。 如果要访问非静态成员,需要先创建对象。 2.非静态方法中: 可以直接访问静态成员。 可以直接访问非静态成员。 3.原因: 静态成员属于类,加载更早。 非静态成员属于对象,必须创建对象之后才存在。
public class Counter { static int totalCount; int count; public static void showTotalCount() { System.out.println(totalCount); Counter counter = new Counter(); System.out.println(counter.count); } public void add() { count++; totalCount++; } }

7.5 工具类

1.工具类: 存放多个通用功能的类。 2.工具类的常见写法: a.类中的方法都使用 static 修饰 b.构造方法使用 private 修饰,防止外界创建对象 3.使用场景: 某个功能不依赖对象自身数据,只根据参数就能得到结果。
public class ArrayTools { private ArrayTools() { } public static int getSum(int[] arr) { int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } return sum; } public static int getMax(int[] arr) { int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } }
public class Demo13ArrayTools { public static void main(String[] args) { int[] scores = {88, 96, 75, 90}; System.out.println(ArrayTools.getSum(scores)); // 349 System.out.println(ArrayTools.getMax(scores)); // 96 } }

注意:

1.不是所有成员都应该定义成 static。 2.如果数据属于每一个对象自己,就定义成非静态成员变量。 3.如果方法需要使用对象自己的数据,就定义成非静态成员方法。 4.如果方法只依赖传入参数,并且是通用功能,可以考虑定义成静态方法。

第八章.继承

8.1 继承的介绍

1.继承: 子类继承父类,可以使用父类中已有的成员。 2.父类: 多个类中共有内容抽取出来形成的类。 3.子类: 继承父类后,还可以定义自己特有的内容。 4.格式: public class 子类 extends 父类 { } 5.继承的好处: a.减少重复代码 b.提高代码复用性 c.让类和类之间产生关系
public class Animal { String name; public void eat() { System.out.println(name + "正在吃东西"); } }
public class Dog extends Animal { public void guardHome() { System.out.println(name + "正在看家"); } }
public class Demo14Extends { public static void main(String[] args) { Dog dog = new Dog(); dog.name = "小黑"; dog.eat(); // 小黑正在吃东西 dog.guardHome(); // 小黑正在看家 } }

8.2 继承的注意事项

1.子类可以继承父类中的非私有成员,并可以直接使用。 2.子类也会继承父类中的私有成员,但是不能直接访问。 需要通过父类提供的 get/set 方法间接访问。 3.构造方法不能被继承。 4.静态方法可以被继承,但是不能被重写。 5.继承主要从"能不能使用"的角度理解,不要简单理解成"复制了一份"。

8.3 继承中成员变量访问特点

1.子类和父类成员变量不重名: 直接访问即可。 2.子类和父类成员变量重名: 看等号左边的类型是谁,优先访问谁中的成员变量。 3.在子类方法中访问重名变量: 局部变量名 -> 局部变量 this.变量名 -> 子类成员变量 super.变量名 -> 父类成员变量
public class Parent { String text = "父类成员变量"; }
public class Child extends Parent { String text = "子类成员变量"; public void show() { String text = "局部变量"; System.out.println(text); System.out.println(this.text); System.out.println(super.text); } }
public class Demo15Variable { public static void main(String[] args) { Child child = new Child(); child.show(); Parent parent = new Child(); System.out.println(parent.text); // 父类成员变量 } }

8.4 继承中成员方法访问特点

1.子类和父类成员方法不重名: 直接调用即可。 2.子类和父类成员方法重名: 看 new 的是谁,优先调用谁中的成员方法。 3.如果子类没有对应方法,再去父类中查找。
public class Printer { public void print() { System.out.println("普通打印"); } }
public class ColorPrinter extends Printer { public void print() { System.out.println("彩色打印"); } }
public class Demo16Method { public static void main(String[] args) { Printer p1 = new Printer(); p1.print(); // 普通打印 ColorPrinter p2 = new ColorPrinter(); p2.print(); // 彩色打印 Printer p3 = new ColorPrinter(); p3.print(); // 彩色打印 } }

8.5 方法重写

1.方法重写: 子类中出现和父类方法名、参数列表都相同的方法。 2.使用场景: 子类需要对父类已有方法进行重新实现或升级改造。 3.@Override: 写在重写方法上方。 如果方法没有正确重写,编译器会报错。
public class Payment { public void pay(double money) { System.out.println("支付金额:" + money); } }
public class WeChatPayment extends Payment { @Override public void pay(double money) { System.out.println("微信支付:" + money); } }
public class Demo17Override { public static void main(String[] args) { WeChatPayment payment = new WeChatPayment(); payment.pay(88.8); // 微信支付:88.8 } }

重写注意事项:

1.方法名必须相同。 2.参数列表必须相同。 3.子类方法权限必须大于等于父类方法权限。 public > protected > 默认 > private 4.私有方法不能被重写。 5.构造方法不能被继承,也不能被重写。 6.静态方法可以被继承,但是不能被重写。 7.重写方法的返回值类型一般和父类保持一致。

8.6 继承的特点

1.Java 只支持单继承: 一个子类只能直接继承一个父类。 2.Java 支持多层继承: 子类可以作为其他类的父类。 3.Java 支持一个父类有多个子类: 多个子类可以继承同一个父类。
public class GrandFather { } public class Father extends GrandFather { } public class Son extends Father { }
public class Animal { } public class Cat extends Animal { } public class Dog extends Animal { }

错误写法:

public class A { } public class B { } /* public class C extends A, B { } */

8.7 继承中构造方法的特点

1.创建子类对象时,会先初始化父类,再初始化子类。 2.每一个构造方法的第一行默认都有 super()。 3.super(): 表示调用父类空参构造。 4.如果父类没有空参构造,子类构造方法中必须手动调用父类有参构造。
public class Person { private String name; public Person() { System.out.println("Person 空参构造"); } public Person(String name) { this.name = name; System.out.println("Person 有参构造"); } public String getName() { return name; } }
public class Teacher extends Person { public Teacher() { System.out.println("Teacher 空参构造"); } public Teacher(String name) { super(name); System.out.println("Teacher 有参构造"); } }
public class Demo18Constructor { public static void main(String[] args) { Teacher t1 = new Teacher(); System.out.println("=========="); Teacher t2 = new Teacher("苏老师"); System.out.println(t2.getName()); // 苏老师 } }

第九章.super 和 this

9.1 super 的使用

1.super: 代表父类引用。 2.super 可以调用: 父类构造方法 父类成员变量 父类成员方法 3.格式: super() 调用父类空参构造 super(实参) 调用父类有参构造 super.变量名 调用父类成员变量 super.方法名() 调用父类成员方法
public class Vehicle { String type = "交通工具"; public Vehicle() { System.out.println("Vehicle 空参构造"); } public Vehicle(String type) { this.type = type; System.out.println("Vehicle 有参构造"); } public void move() { System.out.println("交通工具可以移动"); } }
public class Car extends Vehicle { String type = "汽车"; public Car() { super("车辆"); System.out.println("Car 空参构造"); } public void show() { System.out.println(this.type); // 汽车 System.out.println(super.type); // 车辆 super.move(); // 交通工具可以移动 } }
public class Demo19Super { public static void main(String[] args) { Car car = new Car(); car.show(); } }

注意:

1.super() 或 super(实参) 只能写在子类构造方法中。 2.如果写了 super() 或 super(实参),必须放在构造方法第一行。

9.2 this 的使用

1.this: 代表当前对象。 2.this 可以调用: 本类构造方法 本类成员变量 本类成员方法 3.格式: this() 调用本类空参构造 this(实参) 调用本类有参构造 this.变量名 调用本类成员变量 this.方法名() 调用本类成员方法
public class Course { private String name; private int hour; public Course() { this("Java 基础", 80); } public Course(String name, int hour) { this.name = name; this.hour = hour; } public void print() { this.showTitle(); System.out.println(name + "," + hour); } public void showTitle() { System.out.println("课程信息"); } }
public class Demo20This { public static void main(String[] args) { Course c1 = new Course(); c1.print(); Course c2 = new Course("Java 面向对象", 96); c2.print(); } }

注意:

1.this() 或 this(实参) 只能写在本类构造方法中。 2.如果写了 this() 或 this(实参),必须放在构造方法第一行。 3.同一个构造方法中不能同时写 this() 和 super()。 4.因为二者都要求必须在构造方法第一行。

第十章.父类私有成员赋值

10.1 通过 set 方法赋值

public class Worker { private String name; private int age; public Worker() { } public Worker(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public class Programmer extends Worker { }
public class Demo21SetPrivate { public static void main(String[] args) { Programmer programmer = new Programmer(); programmer.setName("顾南"); programmer.setAge(28); System.out.println(programmer.getName() + "," + programmer.getAge()); // 顾南,28 } }

10.2 通过父类构造方法赋值

public class Designer extends Worker { public Designer() { } public Designer(String name, int age) { super(name, age); } }
public class Demo22SuperConstructor { public static void main(String[] args) { Designer designer = new Designer("唐宁", 26); System.out.println(designer.getName() + "," + designer.getAge()); // 唐宁,26 } }

注意:

1.父类私有成员不能在子类中直接访问。 2.可以通过父类 public 的 get/set 方法间接访问。 3.也可以在子类构造方法中通过 super(实参) 调用父类有参构造完成赋值。

第十一章.本篇小结

1.类是对象的设计图,对象是类的具体实例。 2.成员变量描述对象有什么,成员方法描述对象能做什么。 3.private 可以隐藏成员变量,get/set 方法负责对外访问。 4.this 代表当前对象,常用于区分成员变量和局部变量。 5.构造方法用于创建对象,也可以在创建对象时给属性赋值。 6.标准 JavaBean 通常包含私有成员变量、空参构造、有参构造和 get/set 方法。 7.static 成员属于类,不属于某一个对象。 8.工具类通常构造私有化,方法静态化。 9.继承可以减少重复代码,子类可以使用父类已有成员。 10.方法重写用于在子类中重新实现父类方法。 11.super 代表父类引用,this 代表当前对象。 12.父类 private 成员可以通过 get/set 或父类构造方法间接赋值。
http://www.jsqmd.com/news/793907/

相关文章:

  • Error response from daemon: client version 1.52 is too new. Maximum supported API version is 1.43
  • 【测试】之概念篇
  • 小白通俗易懂吃透XXL-JOB:从原理到架构,一篇就够
  • 手把手教你做——助睿实验作业1-订单利润分流数据加工(零代码ETL + 多表关联 + 条件分流),附完整操作步骤
  • Diablo Edit2:暗黑破坏神2角色编辑器完全指南,3步打造完美游戏体验
  • 基于Vue3的一站式AI服务聚合平台开发与部署实战
  • 对比自行搭建代理与使用Taotoken聚合服务在维护精力上的感受
  • txtskills:将llms.txt文档一键转换为AI助手可调用技能
  • 小型嵌入式系统开发流程与实践指南
  • AI驱动材料发现:生成模型、数据集与未来挑战综述
  • 【2026年05月10日】AI编程技术日报 - 每日精选 [特殊字符]
  • 现代JavaScript/TypeScript工具库架构设计与实现指南
  • 带式输送机托辊移动集声故障诊断与多普勒校正【附仿真】
  • 程序员转智能体开发,这8个核心技能,少一个都不行
  • 智能体工程方法论:从AI辅助编码到可控软件开发的范式升级
  • Windows Defender控制权争夺战:开源工具Defender Control的技术解析与实践指南
  • LLMs之Benchmarks:《ProgramBench: Can Language Models Rebuild Programs From Scratch?》翻译与解读
  • 搭建DevOps企业级仿真实验环境:011Kubernetes 核心架构与组件
  • ClawPowers-Agent:基于LLM的智能体框架设计与实战指南
  • ChatAnywhere聚合AI网关:国内开发者低成本调用GPT/Claude等大模型API实战指南
  • TikTok评论数据提取:开源工具TikTokCommentScraper的技术实现与实战应用
  • S4 HANA 1809+折旧过账(AFAB/AFABN)凭证行数据存储逻辑变迁:从BSEG到ACDOCA的深度解析
  • Vivado HLS数据流优化技术与FPGA性能提升实践
  • FuSa DFMEA在芯片验证中的借鉴价值
  • 智能天线技术:原理、应用与工程实践
  • 为什么你的评分卡在B银行是神器,在C平台就是废纸?
  • 如何用Untrunc开源工具快速修复损坏视频:完整操作指南
  • Linux桌面光标隐藏工具unclutter-xfixes:原理、编译与配置指南
  • DNS 服务器学习笔记:核心总结与实验指南
  • 10款团队任务管理软件对比:从进度跟踪到项目协作