Java基础(一)

JAVA核心技术优势:
跨平台性:操作系统面向对象:
1.多线程
2.健壮性
3.安全性
4.高性能
5.简单性
6.分布式、
JVM虚拟机:JVM运行环境:
JREJRE包含JVM开发环境------>开发工具集:jdk
JDK包含JRE

Java基础概念:
java 的三个平台:JavaSE(标准版,用于桌面应用开发)JavaEE(企业版,用于企业级应用开发)JavaME(微缩版,用于早期嵌入式开发)

包命名规范:域名反写(并且是全小写)
标识符命名规范:可以由数字、字母、下划线、$符号组成,但是不能是关键词,不能以数字开头

基本数据类型:(变量小转大自动转,大转小需要强制转"需要在值后面+数据类型的首字母大写,如:long t=12312345611123L;")所有的基本数据类型都不能自动转换为byte,所以需要使用强制转换,使用强转需要注意避免精度损失以及数据溢出。整数类型:
byte 1字节(只有一个字节的byte 可以自动转换为short,其他类型都需要强制转换。)
short 2字节
int 4字节-----默认 的基本数据类型
long 8字节 浮点类型:
double 8字节-----默认的
float 4字节字符型:
char 2字节(可以存任何一个字符中英文大小写)
布尔类型:boolean(代表真假) 1字节(值只有true 和false)
例子:
short number=5;
int n=6;
number+=n; // 这句代码等于 number = (short)(number+n); +=,-=…都含有隐式的强制类型转换
number = (short)(number+n);强调:char 字符型:当我们给char赋值为数字的时候,其会去根据字符编码表自动转换为对应的字符。byte,short,char 都可以自动转int,其他类型需要强转。byte,short,int,char 都可以自动转long,而浮点型需要强制转换只有double 不能自动转为float
所有基本数据类型都能自动转为double虽然char是两字节,但是在类型转换的时候因为其优先级是最低的,所以所有类型都不能自动转换为char
1:boolean 不能参与数据类型的转换
2:自动转换的时候浮点型的优先级最高,char的优先级是最低的。
3:相同类型的数据(单纯整数,或单纯浮点)字节数较小的可以自动转换为字节数较大的类型。
4:强制转换容易造成精度损失以及数据溢出
变量:我们可以将变量看成一个盒子,盒子里面用来存放我们的数据,我们可以直接通过变量来操控里面的值变量的重点在于变字上面,我们可以对变量进行多次的赋值(初始化),让其在不同地方的代码有不同的值。
变量的创建分为两步:
1:声明变量 类型 变量的名称;
2:初始化变量 变量名 = 值;
上面的两步 可以合并为一句代码: 类型 变量名 = 值;

常量:我们可以将常量看成一个特殊的盒子,里面存放的也是我们的数据,但是这个数据是长久不变的。 被final关键字修饰的变量就叫做常量。final int J=7;J=17; (程序出错,因为"常量"的值不能被修改。);System.out.println(“这是常量”+J);但是可以这样写: final int N; N=18; System.out.println(N);

运算符优先级的问题优先级 运算符 类 结合性:

1: () 括号运算符 由左至右 +(正号)、-(负号) 运算符 由左至右

2 :~ 位逻辑运算符 由右至左2 ++、-- 递增与递减运算符 由右至左

3: *./,% 算术运算符 由左至右

4: +、- 算术运算符 由左至右

5 : <<、>> 位左移、右移运算符 由左至右

6: >、>=、<、<= 关系运算符 由左至右

7 : 、!= 关系运算符 由左至右 使用对比基本数据类型的时候 对比的是值本身,与类型无关

8: & 位运算符、逻辑运算符 由左至右

9: ^ 位运算符、逻辑运算符 由左至右

10: | 位运算符、逻辑运算符 由左至右

11: && 逻辑运算符 由左至右

12: || 逻辑运算符 由左至右&&: 用于多条件并行使用,只有所有的条件都为true,返回结果才为true; 当左侧条件不成立的时候,就不再执行右侧代码 &: 用于多条件并行使用,只有所有的条件都为true,返回结果才为true。当左侧条件不成立的时候,依然执行右侧代码。||: 用于多条件选一的时候,只要有一个条件为true结果就为true当左侧条件成立的时候,则不再执行右侧代码 |: 用于多条件选一的时候,只要有一个条件为true结果就为true当左侧条件成立的时候,依然执行右侧代码

13: ?条件运算符 由右至左

14: =、+=、-=、*=、/=、%= 赋值运算符、扩展运算符 由右至逻辑与、逻辑或、逻辑非的优先级一定要熟悉!(逻辑非>逻辑与>逻辑或)。如:a||b&&c的运算结果是:a||(b&&c),而不是(a||b)&&c

15: 三目运算符: ? : ? 前面放一个boolean表达式 ? 后面放 当前面表达式为true 或false 时候的代码 两段代码中间用:分割(三目运算符可以嵌套,但是不建议嵌套层数过多。)例子如下: System.out.println(5>3?6<7?8==9?“天黑了”:5!=5?“5不等于5”:“5等于5”:“6大于7”:“5小于3”);

16: 数字运算符:+,-,*,/,%,++,–++ 如果放在后面,代表先使用变量本身的值,然后在进行自增1的操作++ 如果写在前面,代表先进行自增1的操作,然后在使用值–:(同上++用法)
17: 字符串连接符:+ 链接多个字符串使用的,当字符串拼接到数字的时候,数字也会变成字符串;优先运算符: () 程序是从上往下,从左往右执行的,可以将内容写在小括号内会优先进行运 算
18: 转义字符: 输出一个双引号:System.out.println(“”“);
输出一个单引号System.out.println(” ’ “);
输出一个斜杠System.out.println(”\“);
\n 换行System.out.println(”\n");
\t 水平制表符(多个空格)System.out.println(“\t”);

public :公开的
static:静止的
void:无返回值
main:( String[] args){}输出:system .out.println ();println:代表先输出,然后进行换行操作,也就是说在输出语句执行之后,光标会在下一行print :不换行输出;out: 是正常输出, err 输出是红色的,经常用于输出错误信息。
访问修饰符有四种:
1.private(私有的)
2. protected(受保护的)
3. public(公开的)
4. 默认不写,
类方法和变量修饰符:abstract class extends final implements interface native new static strictfpsynchronized transient volatile
程序控制:break continue return do while if elsefor instanceof switch case default
错误处理:try catch throw throws
包相关:import package 基本类型:boolean byte char double float int longshort null true false
变量引用:super this void 保留字:goto const
jar包:
什么是jar包?:jar包实际上就是一个特殊的压缩包,只是里面存放的都是我们.java文件编译出来的.class文件。我们的jar之中有很多的jar包,这些jar包都是Java提供给我们的工具类(例如修理工的 扳手,螺丝刀等…),这些类我们直接使用就可以。

导包:当我们使用其他包下的类的时候,需要导包操作,因为类的名称我们可以自己定义,所以很有可能出现不同包下类名重复的现象,所以在使用其他包下的类的时候,需要进行导包操作,避免使用到错的类。

引用数据类型: * 引用数据类型: *

  • 1:类(所有的类,包括我们自己写的类都算引用数据类型)
  • 2:接口(后面讲)
  • 3:数组
  • 4:枚举
  • 类也是一个数据类型,所以我们在使用的时候一般也需要创建一个变量出来,然后我们通过变量名来操控这个类。

创建一个类的变量分为以下两步

  • 1:声明 类名称 变量名;

  • 2:初始化 变量名=new 类名(参数);

  • 上面两步可以合成一步: 类名 变量名 = new 类名(参数);

  • Scanner 扫描流: 这个类可以让我们在控制台输入内容到我们的程序之中.我们可以通过他的变量名.方法名() 来调用里面的方法。
    String 字符串类:字符串虽然也是一个类,但是可以使用创建基本数据类型的方式来进行创建/在Java中所有的字符串都使用String来表示,创建一个字符串变量有两种方式。

  • 1:使用创建基本数据类型的方式来实现:String string = “asdsd”;

  • 2:使用创建引用数据类型的方式来实现:String string2 = new String(“哈哈”);

  • 注意:使用基本数据类型方式创建出来的字符串存储在Java的常量池之中变量名直接指向常量池里面的值,而使用new 创建出来的字符串会在堆内存开辟一个空间, * 而变量名指向的是堆内存的地址,所以字符串不能直接使用==来判断是否相等。

  • 注意:想要判断两个字符串是否相等,可以使用 变量名.equals()方法来判断两个字符串是否相等。
    scanner扫描器使用方法: Scanner sc; //声明
    sc = new Scanner(System.in);
    // 初始化 Scanner sc = new Scanner(System.in); //等于上面 声明初始化 合一。
    System.out.println(“请输入一个int数字”);
    int number=sc.nextInt(); //这个方法可以让我们在控制台输出一个 int数字,并且这个数字我 们可以使用变量来接收。
    System.out.println(“接收到控制台输入的数字为:”+number); System.out.println(“请输入一个小数”);
    double n = sc.nextDouble();
    System.out.println(“接收到控制台输入的数字为:”+n);
    string类型的扫描器写法: Scanner sc = new Scanner(System.in);
    String string4 = sc.next();

*随机数(Math.random()10)Math类:
给我们提供了随机数的静态方法,这个随机数的范围在 0.00000001~ 0.99999之间 最大无线接近1 最小无线接近0 * 如果让这个数乘以10的话 会变成最大 9.9999999 ~ 0.00000010 * 将上面的数字转换成int数字会变成随机的9~0 System.out.println((int)(Math.random()*10)+1);
// 1~10的随机数
例子: 使用随机数,生成一个随机的大写A~大写Z的 字符 1:需要多少位随机数 0~25 随机数 0~25 + 65 System.out.println((char)((int)(Math.random()*26)+65)); }

if的语法: if(布尔表达式){ 表达式为true时候执行的代码。 }else{ 表达式为false时候执行的代码。 } if 是可以进行嵌套的,与三目运算符一样 if 类似于我们说的 如果 也就是条件成立才 会发生的事情,else类似于我们说的否则,只有当if不成立才会进入到else之中。
例子1: 从控制台输入一个数字,如果数字<=5输出上班, 如果数字大于5输出 休息 Scanner sc = new Scanner(System.in); System.out.println(“请输出数字”); int i = sc.nextInt(); if(i<=5){ System.out.println(“上班”); }else{ System.out.println(“休息”); }例子2:(if和三目运算一样,可以嵌套)//从控制台输入一个数字,如果数字<=5输出上班, 如果数字大于5输出 休息,如果输入的数字范围不再1~7之间则提示输入错误 if (i>0&&i<8) {// 数字大于0 并且小于8 if (i<=5) { System.out.println(“上班”); }else { System.out.println(“休息”); } }else { System.out.println(“输入错误”); }
if(){}else if(){}else{};用法使用else 来对if 进行连接,使得所有的if只会同时执行一个
例子1:if (age<13) {
System.out.println(“小孩”);
}else if(age <17){
System.out.println(“青少年”);
}else if(age < 25){
System.out.println(“青年”);
}else if(age<41){
System.out.println(“阿姨”);
}else{
System.out.println(“婆婆”);
}

for循环(流程控制语句之for循环)循环都需要有一个开始条件,也需要有一个结束条件,而一般的循环都需要一个计数器。

  • for(声明变量(声明一个计数器);循环条件;改变迭代计数器的值){ * 符合循环条件的时候执行的代码 } * for循环执行顺序:for(int i=1;i<11;i++){} *
  • 1:int i=1 第一步执行创建变量的操作,并且这一步骤不进入本身的循环。
  • 2:i<11; 第二步执行判断循环条件的操作,并且每一次循环都会执行此步骤直到循环结束
  • 3:代码 第三步执行循环作用域中的代码,每次循环都会执行一次。
  • 4:i++ 第四布执行改变初始变量值的操作,每次循环都会执行一次。
    例子:输出10遍hello java for(long i=1;i<11;i++){ System.out.println(“第”+i+“次 Hello java”); }
    (2)int i=1; for(;i<10;){
    System.out.println(i);
    i++;
    }
    注: for循环的小括号内可以不写任何东西,但是必须要有;但是虽然语法上支持这样写,可是不建议大家使用。

(3)经典for循环水仙花写法求1000以内的水仙花数 水仙花数为:水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身例如 153是水仙花数111+555+333=153 int q,w,e=0; // 用来记录,个位,十位,百位 for (int i = 100; i < 1000; i++) { q=i/100; // 求出i的百位数 w=i%100/10;
求出i的十位数 e=i%10;
求出i的个人数
if (qqq+www+eee==i) {
个位的3次幂+十位的3次幂+百位的3次幂=i本身代表i就是水仙花数 System.out.println(i);
}
}

使用for循环写一个乘法口诀表:
for (int i =1; i <10; i++) {
外层for循环控制的是行数
for (int j =1; j <=i; j++) {
内层for循环控制输出,外层for循环每次迭代的时候,内层for循 环中的J都会重新初始化
System.out.print(j+““+i+”="+(ji)+”\t");
}
System.out.println();
}

100以内的所有质数 (1个数只能被1和他本身整除称之为质数)int sum=0; //记录有多少个质数
for(int i =2;i<101;i++){ //循环100次
boolean a=true; // 设置一个布尔变量
for (int j = 2; j <i; j++) { //尝试i能否被比自己小的数整除 if (i%j==0) { //代表i能被j整除,那就代表i不是质数
a=false; // 如果i不是质数a=false
}
}
if (a) { // 如果a等于true代表i是质数
sum++;
System.out.println(“第”+sum+“个质数为:”+i);
}
}

Switch分支选择语句switch分支选择语句:

  • switch (值) {
    case 值: 当前case中的值 与switch小括号中的值如果一致,则执行这里的代码(case中的值不能重复)
    break;
    case 值: 当前case中的值 与switch小括号中的值如果一致,则执行这里的代码(case中的值不能重复)
    break;
    default:
    当所有case中的值都没有与switch匹配成功的话,则执行default中的值() break;
    switch:只支持具体的值的对比,不支持范围对比,switch 支持byte,short,int,char,string,枚举
    }

例:
String number = “3”; switch(number){
case “1”:
System.out.println(“这是第一个case”);
break;
case “2”:
System.out.println(“这是第二个case”);
break;
case “3”:
System.out.println(“这是第三个case”);
break;
default:
System.out.println(“所有的case都没匹配成功才执行我”);
break;
}
注:continue: 代表跳过本次迭代,继续开始下一次循环。(注意:continue必须写在所在作用域的最下面,其下面不能再有其他代码,因为注定不会执行。)break:打断当前作用域的代码。(可以破坏当前作用域的代码,如果写在循环之内,默认停止最内层循环,可以使用break标记来破坏指定层次的循环。)case的穿透性:case 有一个特性就是当与switch匹配成功的时候,接下来的所有case都不再进行匹配,而是直接执行里面的代码,所以需要在每一个case下面加上break,用来打断switch代码,来防止case的穿透性。当然我们也可以利用case的穿透性。
关于case的穿透性的例子:
int n= 3;
switch (n) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println(“上班”);
break;
default:
System.out.println(“休息”);
break;
}
break的特殊用法:gdfgdfg:for (int i = 1; i < 5; i++) { System.out.println(i+“第一层循环”);
for (int j = 1; j < 5; j++) {
System.out.println(j+“第二层循环”);
for (int j2 = 1; j2 < 5; j2++) {
System.out.println(j2+“第三层循环”);
for (int k = 1; k < 5; k++) {
System.out.println(k+“第四层循环”);
if (k==2) {
break gdfgdfg; }
}
}
}
}

while循环: * while(循环条件){ 条件为true 则循环,为false则停止循环。 * 循环的代码。 * 由于while循环的小括号内不能声明变量,所以我们需要把循环条件的变量定义在循环上面,然后尽量在循环体内去改变变量的值,好用于控制循环。}

注意:1* for循环一般用于明确循环次数的时候使用。2 * while循环一般用于不明确循环次数的时候使用一般经常用于io流,分析结果集等。3* for循环与while循环都是有可能不执行的循环体,因为两者在执行之前都会先判断条件是否成立,如果不成立则不执行循环。
简单的例子:int i = 0; while (i >5) { System.out.println(“第”+i); i++; }
do…whiledo{ * 循环的代码 } while(循环的条件);
注: do while 是最少执行一次的循环体,因为do while 是先执行循环体,然后在判断循环条件的顺序。

do…while简单的例子:问题:输入合格或者不合格,如果合格循环结束,反之则继续循环Scanner sc= new Scanner(System.in);
String next=“”; do{
System.out.println(“检查作业是否合格”);
next = sc.next();
}
while(next.equals(“不合格”));
System.out.println(“奖励小明”);

数组
什么是数组: 我们可以把数组看成一个调料盒,里面可以放多个相同类型的数据。为什么要用数组:假设现在我们需要录入30个学生成绩,如果使用变量需要定义30个,但是使用数组我们只需要一个数组就解决了。 * 数组的缺点: * 1:一个数组,只能存放一种类型的数据。

  • 2:数组在创建的时候就已经制定了长度,我们无法改变。
    • 数组的创建: * 方式一:动态初始化。 * 声明: 类型 [] 变量名; * 初始化: 变量名 = new 类型[长度]; * 上面两步 可以合成一步: 类型[] 变量名 = new 类型[长度]; * 方式二:静态初始化。 * 类型 [] 变量名={值1,值2。。。。。}; * 静态初始化在声明数组的同时对其进行了赋值的操作,里面有多少值就代表长度是多少。
      • 对于数组的操作:
        * 1:声明一个数组
      •  2:初始化数组		
        
      * 		3:赋值		 
      * 		4:取值
      

数组的元素:

1:数组名:数组的名称,我们可以在代码中定义多个数组,使用的时候根据数组名来进行区分。
2:元素: 数组里面的每一个值(数据)都叫做元素。
3:长度: 数组的长度决定了里面可以存放多少个元素。 数组名.length 可以获得数组的长度。
4:索引: 数组里是一个一个的格子,索引代表了格子的位置,索引从0开始计算,永远比长度小一位,通过索引对数组进行取值以及赋值。

数组的默认值

  • 数组在没有赋值的情况下,里面所有的元素都为类型的默认值。 整数:0 小数:0.0 引用数据类型:null
    实例:
    int[] array; 声明
    array = new int[5];初始化
    int [] array2 = new int[5]; 声明的同时进行初始化操作
    int [] array3 = {123,458,87,8,8};
    System.out.println(array[0]);
    System.out.println(array3[2]);
    array[0]=999;
    System.out.println(array[0]);
    System.out.println(array3.length);

数组的遍历:

数组的遍历方式一:
通过传统的for循环遍历。然后通过下标来操控数组,可以对数组进行赋值以及取值。

数组的遍历方式二:
增强for循环,无法通过下标来操控数组,所以只能取值 不能赋值。语法: for(数组的类型 变量名: 需要遍历的数组){ }每一次循环的时候会将数组内的值按照顺序取出,然后赋给我们在for里声明的变量。
int [] array = new int[5];
for (int i = 0; i < array3.length; i++) { // 当i小于数组的长度时候,最后一次循环i的值正好是数组的最后一个索引
System.out.println(array3[i]);
}
for(int i=0;i<array.length;i++){
array[i]=(int) (Math.random()*100000);
}

例一
从控制台循环录入5个整数,存入到int数组之中。

java.lang.ArrayIndexOutOfBoundsException 数组下标越界异常
Scanner sc = new Scanner(System.in);
for (int i = 1; i <=array.length; i++) {
System.out.println(“请输入第”+i+“个数字”);
array[i-1]=sc.nextInt();
}

例二
取出录入数字中的最大值

Scanner sc = new Scanner(System.in);
for (int i = 1; i <=array.length; i++) {
System.out.println(“请输入第”+i+“个数字”);
array[i-1]=sc.nextInt();
}
int max=array[0]; //取出数组第一个元素
for (int i = 1; i < array.length; i++) {
if (max<array[i]){ //如果max小于 数组中的元素 max=array[i]; // max就等于比他大的值
}
}
System.out.println(“最大值是:”+max);

例三
取出录入数字中的最小值
Scanner sc = new Scanner(System.in);
for (int i = 1; i <=array.length; i++) {
System.out.println(“请输入第”+i+“个数字”);
array[i-1]=sc.nextInt();
}
int min=array[0]; //取出数组的第一个元素
for (int i = 1; i < array.length; i++) {
if (min>array[i]) { //如果min大于数组中的元素 min=array[i]; //让min变成比他小的值
}
}
System.out.println(“最小值是:”+min);

数组

冒泡排序每次都是相邻的两个元素进行比较,如果左边大于右边(或者小于)就互相交换位置
例子1.
int [] array={4356,3458,645,23333,5,811118};
int number=0;
for (int j = 0; j < array.length-1; j++) {
for (int i = 0; i < array.length-1-j; i++) { //由于代码内会用到i+1所以在此-1防止数组越界
if (array[i]<array[i+1]) { //假如下标0的值小于下标1的值 number=array[i]; //把下标0的值赋给 number
array[i]=array[i+1]; //把下标1的值赋给下标0 array[i+1]=number; //把number的值赋给下标1
}
}
}
外层for循环-1 : 数组的长度是6,那么循环5次就可以了。

内层for循环-1 :是因为对比值的时候使用了i+1 为了防止数组越界所以 length-1
内层for循环-j : 是因为外层for循环执行一次之后,最后一个下标中已经是最小值了,第二次就没必要再去对比他了。

数组选择排序

每次都对比出数组最大|最小的值,然后记录其下标,在循环结束后将其放在下标i的位置。

十大经典排序算法网站:https://zhuanlan.zhihu.com/p/34894768

例子1.int [] array={4356,3458,645,23333,5,811118};
for (int i = 0; i < array.length-1; i++) {
int k=i; //记录每一次对比的初始下标
for (int j = i+1; j < array.length; j++) {
if (array[j]>array[k]) { // j的下标值更大
k=j; // 记录值更大的下标
}
}
if (k!=i) { //如果K等于i 那代表i下标本身就是最大的值,没必要进行替换操作 i
nt n =array[i];
array[i]=array[k];
array[k]=n;
}
}
for (int j2 : array) {
System.out.print(j2+" ");
}

Arrays 数组工具类:

  • 1:toString(需要输出的数组)可以将我们的数组转化成字符串。

  • 2:sort(需要排序的数组) 可以将我们的数组进行升序排序。

  • 3:binarySearch(查询的数组, 查询的值)可以返回我们查询的值在数组之中的对应下标。由于底层使用的是二分查找法,所以要求数组必须是排序之后的数组.如果在数组之内找不到值的话会返回负数。

  • 4:fill(数组,值);使用for循环将数组中的值都替换成括号内的值。

  • 5:copyOf(数组, 新数组的长度) * 底层会根据新数组的长度来创建一个数组出来,并将老数组中的值都放入到新数组中,如果新创建的数组长度超过老数组,超出的下标内会填入默认值。

  • 6:copyOfRange(数组, 开始, 结束) 底层会创建出来一个新的数组,然后从哪里开始复制值,复制到第几位结束。(不包含结束本身的索引例如:2,5 只复制下标 2,3,4)

Arrays 数组工具类例子:
int[] array={545,854,24,5,2,45};
Arrays.sort(array);
System.out.println(Arrays.toString(array)); System.out.println(Arrays.binarySearch(array, 5874)); Arrays.fill(array,888);
System.out.println(Arrays.toString(array));
int[] of = Arrays.copyOf(array, 10); System.out.println(Arrays.toString(of));
int[] copyOfRange = Arrays.copyOfRange(array, 2, 5); System.out.println(Arrays.toString(copyOfRange));
int[][] array2 = new int[3][5]; // 有3个一维数组,没个一维数组中可以存放5个值。
System.out.println(array2[0][4]); //先取出第一个一维数组,然后从数组中取下标4的值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郑要做干饭人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值