随笔 - 241  文章 - 1  评论 - 58  阅读 - 85万 

前言

  • 使用数据类型声明、初始化变量,用于在内存中保存需要运算的数据;
  • 使用运算符对内存中保存的数据(变量)进行运算;
  • 使用循环控制语句对运算流程进行控制;
  • 使用面向对象思想对数据和运算流程进行封装,实现功能更加复杂的程序 ;

1.面向过程编程和面向对象编程思想的区别?

面向过程和面向对象编程是2种不同的编程指导思想,都是在说明应该以什么形式组织代码?使用代码? 

面向过程:是一种以过程为中心的编程思想,实现功能的每一步都是自己实现的

面向对象:是一种以对象位中心的编程思想,通过指挥对象实现具体功能。

例如:

如果我想吃饭,首先想到找1个饭店(面向对象),而不是自己买面然后架锅然后生火然后煮饭(面向过程)。

如果我想喝酒,首先想到找1个酒吧(面向对象), 而不是自己买粮食然后自己酿造(面向过程)。

如果我想回家,首先想到找1辆出租车(面向对象),而不是自己造车然后自己驾驶(面向过程)。

由于日常生活中我们就是采用面向对象思想去解决问题的,在编程时也同样采用面向对象思想去解决问题,就会使编程更加简单,代码也会非常易于人去理解

2.面向过程编程和面向对象编程思想的联系?

面向对象和面向过程编程虽然强调了2种截然不同的编程思想,但是在实际编程过程中,2者是相辅相成的,我们即使用面向过程也使用面向对象思想。

面向对象编程思想基于面向过程编程思想的,我们虽然使用类封装了数据和方法,但方法中代码还是需要面向过程来实现功能

 

一、类的组成

 Java的类由属性、方法、构造器方法、代码块(普通块、静态块、构造块、同步块)内部类构成。

 

二、属性

属性也称为成员变量,属性决定了该类封装的数据信息。

成员变量和在方法中定义的局部变量有以下区别。

区别 成员变量 局部变量
类中位置不同 定义类中方法外 定义在方法中
初始化默认值不同 有默认初始化值 没有默认初始化值,必须先赋值才能使用
内存位置不同 堆内存 栈内存
生命周期不同 随对象创建而存在,随对象消失而消失 随方法的调用而存在,随方法的运行结束而结束
作用域 成员变量可以在类中任意使用 局部变量只能在方法(大括号{})中使用

 

三、方法

Java中没有函数的概念,只有类和方法,方法是一快具有特殊功能的代码,提高了代码的复用性,解决了代码冗余现象。

有以下特点:

  • main方法是Java虚拟机默认调用的是程序的入口
  • 方法定义时需要加修饰符
  • 方法不支持嵌套
  • 参数不能使用默认值(方法重载来实现)
  • 只能有1个返回值

 

1.方法的基本语法

Jav中程序自动以主方法main(),作为程序执行的入口

public static void main(String[] args)public:

 

2.方法的构成

方法由方法头和方法体2大部分构成;

A.方法头:方法头由如下元素构成

--------------------------------------------------------------------------------------------------------------------

访问控制修饰符:

  public protected default(空的) private
同包同类
同包不同类 ×
不同包有继承关系 × ×
不同包无继承关系 × × ×

 

public: 该方法可以在项目任意位置使用。   

default: 该方法只允许在同一个包中进行访问。

protected: 该方法只允许被类本身的方法及子类访问(介于public 和 private 之间)。

private: 该方法只允许在当前类中进行访问。 

--------------------------------------------------------------------------------------------------------------------

静态修饰符

static: (静态修饰符):static修饰的内容保存在方法区中的静态区, 在类加载的时候静态区中的内容就已经初始化完成,内容只有1份、不依赖任何实例即可调用。

--------------------------------------------------------------------------------------------------------------------

返回值

void: 方法的返回值类型如 int double、String...等类型

--------------------------------------------------------------------------------------------------------------------

方法名称

main:方法名

--------------------------------------------------------------------------------------------------------------------

方法参数列表:方法列表定义了调用该方法需要传入的参数

--------------------------------------------------------------------------------------------------------------------

B.方法体:方法具体运算的代码

 

3.方法的参数

Python中参数是引用传递,在Java中只有值传递,基本数据类型传递具体值,引用类型传递地址值;

当参数是基本数据类型时,形参和实参是2个完全不同的值,都归属于自己的方法空间内;

当参数是引用数据类型时:形参和实参是2个堆内存地址值,但是指向了同一块堆内存。

复制代码
import java.util.Arrays;

public class ArgsOption {
    public static void main(String[] args) {
        int i = 10;
        int[] j = {1, 2, 3};
        change(i);
        //当实参把数据传递给形参时,分为按值传递和按引用传递;
        System.out.println(i);
        change(j);
        System.out.println(Arrays.toString(j));
    }

    //数据按值传递:传递值会被重新赋值为另一份;
    public static void change(int i) {
        i = 100;
    }

    //数据按引用传递:就相当于Golang中传递是内存地址
    public static void change(int[] b) {
        b[0] = 100;
    }


}
复制代码

可变参数

1个方法的参数列表中可以存在1个可变参数,该可变参数必须是参数列表中最后1个参数;

复制代码
import java.util.Arrays;

public class ArgsOption {
    public static void main(String[] args) {
        int[] array1 = {1, 2, 3};
        change(array1);
        change(1, 2, 3, 4, 5, 6, 7);
    }

    public static void change(int... array) {
        for (int i : array) {
            System.out.println(i);
        }
    }


}
复制代码

 

4.方法重载(Overloading)

方法重载的概念:方法重载描述的是一个类中多个方法的关系,如果在同一个类中,多个方法的名称完全相同但参数列表不同的即构成了方法重载。

方法重载的作用:降低了使用者调用方法成本,可以将一系列目的相同的方法指定为同一个方法名称,根据传递的参数不同自动匹配对应的方法。

方法重载的无关性:方法重载和返回值类型、参数列表的变量名、方法前面的修饰符无关

方法重载的有关系:在同一个类中多个方法的名称相同,但参数列表不同(参数数据类型、参数顺序、参数个数不同)。

复制代码
public class ReloadMethod {
    public static void main(String[] args) {
        System.out.println(get_perimeter(19, 20));
        System.out.println(get_perimeter(19));
        System.out.println(get_perimeter(19, 3.15));
    }


    public static int get_perimeter(int length, int width) {
        //可以计算长方形的周长
        int perimeter = (length + width) * 2;
        return perimeter;
    }

    public static int get_perimeter(int side) {
        //可以计算正方形的周长
        int perimeter = side * 4;
        return perimeter;
    }

    public static double get_perimeter(int D, double pi) {
        //可以计算圆形的周长
        double perimeter = (double) pi * D;
        return perimeter;
    }


}
复制代码

 

四、构造方法

构造方法是对象实例化过程中调用的方法,在继承关系下,子类初始化时会默认执行父类的构造方法;

当对象实例化时如果类继承了父类,那么先调用对象类父类的构造方法,然后再执行对象类的构造方法。这一点很容易被忽略

  • 对象开始实例化
  • 执行new开辟堆内存空间
  • 先执行父类的构造方法
  • 再执行类的构造方法

那么创建出来的对象在内存中是什么结构呢?

基本数据类型表示1个数据,引用数据类型用于表示1组数据。

数组是Java预先定义好的引用数据类型,我们自己定义的类(Person/Book/Car)本质上也是1种引用数据类型,所以对象也保存在堆内存中。

 

1.单个对象内存图

类实例时执行new关键字本质就是创建了1块堆内存空间,所以new出来的对象,都属于引用数据类型。

 

方法区保存着被加载过的每一个类的信息;这些信息由类加载器在加载类的时候,从类的源文件中抽取出来;

static变量信息也保存在方法区中,类(Class)的元数据,都保存在方法区里;

成员方法和成员变量的元数据都会被加载到方法区中;

当成员方法需要被调用时,当前栈通过对象引用地址找到对象,然后通过对象找到成员方法的引用地址,然后通过成员方法的引用地址去方法区中调用方法,然后进栈。

 

2.什么是深拷贝?

如果2个对象引用指向了2块不同的堆内存空间就是深拷贝。

如果通过类new出了2对象,会在堆内存中创建2块不同的空间,用于保存这两个对象;

这2个对象之间的成员属性是隔离的,体现了对象之间的差异化

这2个对象调用的成员方法是共享的

 

3.什么是浅拷贝?

如果多个对象引用指向了同1块堆内存空间就是浅拷贝;

如果通过类new出了1对象,其他多对象引用指向了这个对象的引用, 那么这些对象引用就会指向同1块堆内存空间,就是浅拷贝。

这些对象访问到的内容都是一样的;

如果其中1个对象通过对象引用修改了堆内存空间中的内容,另一个也会改变;

 

五、代码块

代码块执行完毕后占用的内存空间会被立即释放,因此使用代码块可以节省内存开销;

在Java的类中可以定义普通代码块构造代码块、静态代码块、同步代码块(线程再议)

普通代码块:限制变量了声明周期,当普通代码块结束之后,里面定义的变量会在内存中立即释放,从而节省了内存开销。

构造块:当构造方法调用之前会默认执行构造代码块,每次对象实例化时都会执行一次;

静态块:类被加载时执行异常,仅仅执行1次;

他们执行顺序:静态块--》构造块--》普通块

复制代码
package InterClass;

public class TestInter {
    //属性
    int age;

    //方法
    public void a() {
        System.out.println("这是A方法");
        {
            //普通块跟随方法一起执行
            System.out.println("这是一个普通块");
        }
    }

    //1.静态块先执行
    static {
        System.out.println("这是1个静态块");
    }

    //2.执行构造块
    {
        System.out.println("这是1个构造块");
    }

    //构造器
    TestInter() {
    }
}

class Main {
    public static void main(String[] args) {
        TestInter t = new TestInter();
        t.a();
    }
}
复制代码

 

六、面向对象3大特性

1.封装

封装可以保证数据安全,实现高内聚和低耦合。

高内聚:类的内部数据操作细节尽量在类内部使用方法完成,不允许外部干涉;

低耦合:仅对外暴露少量的方法,用于使用;

数据安全:无法通过对象,直接初始化、修改类成员变量,而需要借助构造和set方法;

通俗来讲,封装的设计思想就是把该隐藏的全部隐藏起来,把该暴露的暴露出来;

在Java中1个标准JavaBean封装过程如下:

  • 使用权限修饰符(private、protected、public)将属性隐藏起来,
  • 然后提供相应的set和get方法进行数据的设置和获取;
复制代码
public class Gril {
    //把年龄数据封装保护起来,不让对象直接调用;
    private int age;
    private String name;

    public Gril() {

    }

    public Gril(String name, int age) {
        this.name = name;
        this.setAge(age);
    }


    //提供getAge方法对属性进行获取
    public int getAge() {
        if (this.age >= 29) {
            this.age = 18;
        }
        return age;
    }

    //提供setAge方法对属性进行设置
    public void setAge(int age) {
        if (age < 1) {
            age = 10;
        }
        this.age = age;
    }

}
复制代码

---------------------------------------------调用------------------------------------------------

public class Test {
    public static void main(String[] args) {
        Gril g1= new Gril("Lisa" ,29);
        System.out.println(g1.getAge());
    }

}

 

2.继承

继承是指:类和类直接的一种关系(子父类关系),通过继承可以让子类继承父类的全部内容(子类也可以调用父类pubulic的set和get方法访问父类的私有的内容);

与C++、Python的继续不同,在Java中1个子类只能直接继承1个父类。

2.1.继承关系中成员方法和成员属性的执行流程

先在子类中找,如果子类中没有则去父类;

 

2.2.继承关系中构造方法的执行流程

先调用父类的构造方法;

 

2.3.继承关系中,为什么子类可以通过父类pubulic的get和set方法修改父类的属性?

由于new 子类实例时,会在堆内存中单独再开辟一块super空间,保存了继承自父类成员变量的内容;

当子类对象(this) 调用set/get方法设置/获取值时,会先在当前子类中查找对应成员方法,如果没有则会去父类中找;

所以即使子类无法直接访问父类的成员变量,也可以通过父类提供的set/get方法来进行super空间内容设置/获取。

 

2.4.this和super关键字的特性

this关键字是实现继承(子类和父类数据共享的)关键,因为其特性是this会先在本类中找,如果找不到则会去父类中找。

A.相同点:

this和super都是Java中的关键字都用于指代对象;

B.不同点

super和this关键字指代的对象不同:this指代当前对象,super指代父类对象。

super和this关键字的查找范围不同:super只能查找父类中的成员方法和成员属性,而this可以访问到父类的成员属性和成员方法,因为其特性。(this会先在本类中找,如果找不到则会去父类中找)

 

3.多态

(1).多态概念

多态是指多种形态,多态和属性无关,多态指的是方法的多态;

多态的体现有两种:

大家都是同一类事物,具备同一种行为,   但是具体的表现出来不一样;

大家不是同一类事物,但具备同一种行为,具体表现不一样;

多态宏观体现:同1个方法调用,然后由于传入对象不同,产生不同的行为 。

多态是一种编程思想,对于思想层面的东西,需要从编程实践中慢慢体会;

学习多态的方法是:暂时抛弃概念,只看多态的本质,先去观察多态在代码中是怎么体现的?多态在代码中如何使用?

 

(2).多态构成前提

如何让同一类事物/不同类事物,具备同1种行为呢?

肯定是去继承同一个父类,或者去实现同一个接口,所以实现多态的前提就是:

  • 有继承/实现关系
  • 有方法重写
  • 有父类引用指向子类对象

 

(3).多态在代码中的体现

A.宏观体现:

父类/接口引用指向子类对象/实现类对象,通过宏观体现可以学习多态情况下成员变量和成员方法的访问特点。

父类引用指向子类对象,  成员变量访问特点: 编译看左边(父类引用),运行看左边(父类引用)

接口引用指向实现类对象,成员方法访问特点:编译看左边(接口引用),运行看右边(实现类方法)

B.微观体现:

通过微体现可以学习多态在代码中的使用方式。

多态在代码中的使用方式并不是直接把父类/接口的引用指向子类/实现类对象,而是在定义成员方法时将父类/接口类型作为方法的参数或者作为方法的返回值;(方法定义)

如果将父类/接口类型作为方法的参数,可以传递父类的子类对象/接口实现类的对象作为成员方法的实参(方法传参);

如果将父类/接口类型作为方法的参数,在方法中可以通过形参调用形参的方法和属性(调用形参对象的属性和方法);

复制代码
public class Test {
    public static void main(String[] args) {
        //1.多态宏观体现:接口引用指向实现类对象
        USB mouseDevice = new Mouse();
        USB keyboardDevice = new Keyboard();
        //2.多态的微观体现1:如果一个方法的参数是父类/接口类型,可以传递子类/实现类对象
        UseUSB(mouseDevice);
        UseUSB(keyboardDevice);
    }


    //定义1个方法,可以传入1个鼠标对象,并可以进行对应方法的调用;
    public static void UseMouse(Mouse mouse) {
        mouse.start();
        mouse.run();
        mouse.stop();
    }

    //定义1个方法,可以传入1个键盘对象,并可以进行对应方法的调用;
    public static void UseKeyboard(Keyboard keyboard) {
        keyboard.start();
        keyboard.run();
        keyboard.stop();
    }

    //之前的方法把方法的形参指定的很明确只能传Mouse或只能传Keyboard
    //多态的微观体现2:由于Mouse和Keyboard对象都遵守了USB接口规范,就可以使用多态将USB接口作为方法的形参;
    public static void UseUSB(USB device) {
        //多态微观体现3:如果将父类/接口类型作为方法的参数,在方法中可以通过形参调用形参的方法和属性
        device.start();
        device.run();
        device.stop();
    }
}
多态的体现
复制代码

 

(4).多态优势和弊端:

优势:提高了方法的复用性,实现灵活扩展。

弊端:因为多态情况下成员变量和成员方法的访问特点,只能调用父类的子类/接口的实现类实现了的方法,不能调用实现类对象特有的方法;

 

(5).多态中的转型

通过向上转型和向下转型可以解决多态的弊端;

向上转型:可为将不同的子类归类成一种类型,传到参数里。

向下转型:为了传到函数之后,能获取子类中特有的内容。

向下转型也就是类型之间强转 的条件是:父类变量引用了子类的对象,而不是父类变量引用了父类本身的对象。

复制代码
public static void useAnimal(Animal a) {
        a.eat();
        //instanceof可以判断父类引用到底指向了哪1个具体子类对象?
        if (a instanceof Dog) {
            Dog dog = (Dog) a;    //强转之后进行子类对象特有方法的调用
            dog.watchDoor();
        } else if (a instanceof Cat) {
            Cat cat = (Cat) a;    //强转之后进行子类对象特有方法的调用
            cat.sleep();
        }
    }
多态转型
复制代码

 

(6).简单工厂设计模式

复制代码
package OppTest02;

public class PetStore {
    public static Aniaml getAnimal(String petName) {   //多态的应用场合
        Aniaml pet = null;  //petName.equals("猫"),防止发生空指针异常;
        if ("猫".equals(petName)) {
            pet = new Cat();
        }
        if ("狗".equals(petName)) {
            pet = new Dog();
        }

        if ("猪".equals(petName)) {
            pet = new Pig();
        }

        return pet;
    }
}
复制代码

 

(7).final关键字

一般final用于修饰一些不可变的变量值,被final修饰的变量称为自定义常量;

  • 当final修饰类时,    这个类将无法被继承。
  • 当final修饰属性时,这个属性将无法被修改。
  • 当final修饰方法时,这个方法将无法被重写。

 

七、抽象类

抽象类的设计限制了子类设计的随意性,通过抽象类,子类的设计变得更加严格,使子类更加通用。

当1个子类继承了抽象类之后就必须要实现抽象类中的抽象方法,否则这个子类必须也是1个抽象类;

 

1.抽象类与抽象方法的概念?

抽象:说不清道不明,没有具体的体现形式,都可以称为抽象

抽象方法:方法题中不确定具体执行逻辑的方法称为抽象方法;

抽象类:抽象方法所在的类就是抽象类;

 

2.抽象类与抽象方法的语法格式?

抽象类:

public abstract class Animal{}

抽象方法:

//所有动物都具备吃的行为,但是每一种吃东西的具体细节无法表示;
public abstract void eat();

 

3.抽象类与抽象方法的作用?

抽象方法:

抽取子类共性内容之后,发现父类的抽取的方法无法明确表示具体的逻辑 狗:吃 猫:吃,每一种动物吃食的具体逻辑无法在父类明确,所以将方法作为抽象方法;

抽象类:

抽象类就是给抽象方法提供一个定义环境;

 

4.抽象类和抽象方法的注意事项

抽象类不明确具体逻辑,继承抽象类的子类必须实现该类中定义的所有抽象方法,否则该类无法使用;

抽象类和普通类一样,都可以定义成员变量、成员方法、构造方法,但是抽象类不可以创建对象,抽象类的构造方法存在的意义是让子类对象初始化时进行调用的;

抽象方法一定要在抽象类中,而抽象类中不一定要有抽象方法

 

5.抽象类和抽象方法的使用

定义1个抽象类

复制代码
public abstract class Animal {
    private String name;
    private  int age;

    public Animal() {
    }

    //所有动物都具备睡觉行为
    public void sleep(){
        System.out.println("动物都可以睡觉休息!");
    }
    //所有动物都具备吃的行为,但是每一种吃东西的具体细节无法表示;
    public abstract void eat();
}
复制代码

继承抽象类并实现抽象类中的抽象方法;

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

 

八、内部类

如果1个类只需要使用一次,可以使用匿名内部类,没有必要去声明1个类,在去实例化;

 

1.内部类概述

内部类是Java提供的一种编写代码的方式,指的是在1个类的内部再去定义另外一个类,这个定义在类内部的类称之内部类;

 

2.内部类的作用

Java没有多继承,内部类的存在使得Java的多继承机制变得更加完善;(完善多继承机制)

使用匿名内部类可以快速创建抽象父类的子类对象/实现接口规范的实现类对象;(比较方便);

 

3.内部类分类

  • 成员内部类:使用public、private、static修饰内部类,成员内部类使用外部类的成员变量和方法,在外部任何位置都可以使用;

  • 局部内部类:定义在方法内部方法的类,有类名,出了方法就没用了

  • 匿名内部类(方便),定义在成员方法内部的类,该类没有类名, 出了方法就没用了。匿名内部类本质上就是1个接口/抽象父类的实现类的对象

 

4.成员内部类:

在1个类中定义的类就是内部类,内部类数这个类中的一员, 我们也称这个内部类为成员内部类。

复制代码
        //成员内部类实例化方式1:在外部类中创建对象
        Person p1 = new Person("姚明", 177.212, 90.11);
        p1.showHeart();
        Person p2 = new Person("鸠摩智", 180.212, 80.11);
        p2.showHeart();

        //成员内部类实例化方式1:在外部类外面创建对象
        Person.Heart heart = new Person("乔峰", 180, 80).new Heart(50);
        heart.jump();
复制代码

 

5.局部内部类:

我们还可以在Java的方法内部、代码块内以及构造器方法内定义嵌套内部类,这种内部类叫局部内部类。

 

6.匿名内部类

匿名内部类和局部内部类的唯一区别是匿名内部类没有类名;

匿名内部类把创建子类、覆盖重写抽象方法、创建子类对象,子类对象方法调用这4步合成了1步完成;

匿名内部类的本质就是1个重写了抽象方法的抽象父类的子类对象/重写了所有方法的接口实现类的对象,弊端是这个对象没有名字,仅能使用1次;

 

7.匿名内部类创建格式

new 抽象父类/接口(): //错误:不能直接使用new去实例化抽象父类/接口对象;

new 抽象父类/接口(){ 覆盖重写所有的抽象方法/接口规范; }

复制代码
    public static void main(String[] args) {
        //通过匿名内部类的创建格式:快速创建1个Flyable的实现类对象
        new Flyable() {
            @Override
            public void fly() {
                System.out.println("老鹰展翅翱翔在四方");
            }
        }.fly();


    }
复制代码

 

8.匿名内部类应用场景

当方法的参数声明为父类类型/接口类型,可以使用匿名内部类创建一个子类/实现类对象传入.
当方法的返回值声明为父类类名/接口类型,可以使用匿名内部类创建一个子类/实现类对象返回.

 

九、接口

在Java中类和接口是平行的概念,类是类,接口是接口,接口是一种特殊的引用数据类型,接口一般用于指定规范;

当1个类需要遵守接口中定义的规范时,就去实现该接口,实现接口中定义的方法;

 

1.接口的定义

public interface Inter {
    //1.抽象方法
    void show();

    //2.默认方法:接口中除了可以定义抽象方法之外还可以定义默认方法,对于默认方法,实现类可以实现也可以不实现,约束比较松散;
    default void showTwo() {
    }
}

 

2.接口的组成部分

抽象方法:一般而言,接口中的方法默认就是抽象方法,所以public abstract修饰符可以省略;

默认方法:接口中除了可以定义抽象方法之外还可以定义默认方法,对于默认方法,实现类可以实现也可以不实现,约束比较松散;

 

3.类与接口之间的关系 

(1).类和类的关系:       两个类想要建立关系,只能是继承关系,并且是单继承。

(2).类和接口的关系:    类和接口之间想要建立关系,只能是实现关系,1个类可以实现多个接口;

(3).接口和接口的关系:接口和接口只能建立继承关系,1个接口可以继承多个接口;

 

4.继承抽象类和实现接口的区别?

大家都是同一类事物,需要具备同一行为。(继承抽象类)

大家不是同一类事物,需要备同一行为。    (实现接口)

继承: A is B的关系。手机是照相机。

实现: A has B的关系。 手机具备照相的能力。

 

5.小鸟、飞机、风筝到底是什么关系

定义1个接口 Flyable:小鸟、飞机、风筝 这3个类去实现Flyable接口,之后小鸟能飞、飞机能飞、风筝能飞

而不是抽象出小鸟、飞机和风筝的父类(3者很难抽象出1个父类来!!),之后小鸟、飞机、风筝这3个子类再去继承这个父类。

 

posted on   Martin8866  阅读(75)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示