学习笔记:黑马程序员Java-中级篇(第二部分),2024年最新中级java工程师面试常见问题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

package com.itheima._03接口的实现;
/**
* 接口的实现:
* 在Java中接口是被实现的,实现接口的类称为实现类。
* 实现类的格式:
* class 类名 implements 接口1,接口2,接口3…{
*
*
* }
* */
public class PingPongMan implements SportMan {
@Override
public void run() {
System.out.println(“乒乓球运动员稍微跑一下!!”);
}

@Override
public void law() {
    System.out.println("乒乓球运动员守法!");
}

@Override
public String compittion(String project) {
    return "参加"+project+"得金牌!";
}

}


**测试代码**:



public class TestMain {
public static void main(String[] args) {
// 创建实现类对象。
PingPongMan zjk = new PingPongMan();
zjk.run();
zjk.law();
System.out.println(zjk.compittion(“全球乒乓球比赛”));

}

}


#### 12.3.5案例-多实现


**类与接口之间的关系是多实现的,一个类可以同时实现多个接口。**


首先我们先定义两个接口,代码如下:



/** 法律规范:接口*/
public interface Law {
void rule();
}

/** 这一个运动员的规范:接口*/
public interface SportMan {
void run();
}


然后定义一个实现类:



/**
* Java中接口是可以被多实现的:
* 一个类可以实现多个接口: Law, SportMan
*
* */
public class JumpMan implements Law ,SportMan {
@Override
public void rule() {
System.out.println(“尊长守法”);
}

@Override
public void run() {
    System.out.println("训练跑步!");
}

}


说明:



> 
> ​ 从上面可以看出类与接口之间是可以多实现的,我们可以理解成实现多个规范,这是合理的
> 
> 
> 


### 12.3接口与接口的多继承


​ Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口


注意:


* **类与接口是实现关系**
* **接口与接口是继承关系**


接口继承接口就是把其他接口的抽象方法与本接口进行了合并。


案例演示:



public interface Abc {
void go();
void test();
}

/** 法律规范:接口*/
public interface Law {
void rule();
void test();
}

*
* 总结:
* 接口与类之间是多实现的。
* 接口与接口之间是多继承的。
* */
public interface SportMan extends Law , Abc {
void run();
}


### 12.4JDK8以后接口中新增的方法


* 允许在接口中定义默认方法,需要使用关键字default修饰

 作用:解决接口升级的问题
* 接口中默认方法的定义格式:


	+ 格式: public **default**返回值类型方法名(参数列表){}
	+ 范例:public **default** void show(){ }
* 接口中默认方法的**注意事项**:


	+ 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,**重写的时候去掉default关键字**
	+ public可以省略,**default不能省略**
	+ 如果实现了多个接口,**多个**接口中存在**相同名字的默认方法**,子类就必须对该方法进行重写


示例:



public interface InterA {
/*接口中默认方法的定义格式:
格式:public default 返回值类型 方法名(参数列表) { }

接口中默认方法的注意事项:
1.默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
2.public可以省略,default不能省略
3.如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写*/

public abstract void method();

public default void show(){
    System.out.println("InterA接口中的默认方法 ---- show");
}

}



> 
> 接口中,静态的关键字可以不能省略。
> 
> 
> 接口中,静态的关键字修饰可以又方法体
> 
> 
> 接口中,静态的关键字是为了**解决接口升级的问题**
> 
> 
> 


* 允许在接口中定义定义静态方法,需要用static修饰
* 接口中静态方法的定义格式:
	+ 格式: public **static**返回值类型方法名(参数列表){}
	+ 范例:public **static** void show(){ }
* 接口中静态方法的**注意事项**:
	+ 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
	+ public可以省略,**static不能省略**


示例:



> 
> 在接口中,被static修饰的方法,不能被重写,可以直接调用
> 
> 
> 重写(子类把从父类继承下来的虚方法表里面的方法进行覆盖了,这才叫重写。)
> 
> 
> 


### 12.5JDK9新增的方法


**基本用例**



/*格式:
private返回值类型方法名(参数列表){} */
private void show() { }

/*格式:
private static返回值类型方法名(参数列表){} */
private static void method(){ }


### 12.6接口的应用


#### 12.6.1接口的灵活使用


​ 接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了


![image-20230304192545514](https://img-blog.csdnimg.cn/img_convert/7e821359b3ffdd4595e5fa2ad01a6f34.png)



> 
> 若想让某种javaBean实现某种功能,则实现某种接口即可
> 
> 
> 


#### 12.6.2接口的多态


​ 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为**接口多态**。


![image-20230304193304751](https://img-blog.csdnimg.cn/img_convert/90d11fcc844b93c1282e7c9cfdbb8e6b.png)


说明:



> 
> ​ 如果一个方法中,当参数为接口时,那么在调用方法时就可传递这个接口的所有实现类对象
> 
> 
> 


基本用例:



public class Main {
public static void main(String[] args) {
test(new IHomeServiceImpl());
}
private static void test(IHomeService IHomeService){
IHomeServiceImpl home1= (IHomeServiceImpl) IHomeService;
home1.test();
}


说明:



> 
> ​ IHomeService为接口,那么当这个接口需要什么对象时,new相应对象即可拿到这个接口对应的实现类对象
> 
> 
> 


### 12.7适配器设计模式


请查看接口的细节 第5个


### 12.8接口的细节


关于接口的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。


1. 当两个接口中存在相同抽象方法的时候,该怎么办?



> 
> ​ 只要**重写一次**即可。此时重写的方法,既表示重写1接口的,也表示重写2接口的。
> 
> 
> 


2. 实现类能不能继承A类的时候,同时实现其他接口呢?



> 
> * 继承的父类,就好比是亲爸爸一样
> * 实现的接口,就好比是干爹一样
> * 可以继承一个类的同时,再实现多个接口,只不过,要把接口里面所有的抽象方法,全部实现。
> 
> 
> 


3. 实现类能不能继承一个抽象类的时候,同时实现其他接口呢?



> 
> 实现类可以继承一个抽象类的同时,再实现其他多个接口,只不过要把里面所有的抽象方法**全部重写**。
> 
> 
> 


4. 实现类Zi,实现了一个接口,还继承了一个Fu类。假设在接口中有一个方法,父类中也有一个相同的方法。子类如何操作呢?



> 
> * 处理办法一:如果父类中的方法体,能满足**当前业务的需求**,在子类中可以不用重写。
> * 处理办法二:如果父类中的方法体,不能满足**当前业务的需求**,需要在子类中重写。
> 
> 
> 


5. 如果一个接口中,有10个抽象方法,但是我在实现类中,只需要用其中一个,该怎么办?(重点)



> 
> 1. 可以在接口跟实现类中间,新建一个中间类(适配器类)
> 2. 让这个适配器类去实现接口,对接口里面的**所有的方法做空重写**。
> 3. 让子类**继承**这个适配器类,想要用到哪个方法,就重写哪个方法。
> 4. 因为中间类没有什么实际的意义,所以一般会把中间类**定义为抽象**的,不让外界创建对象
> 
> 
> 


## 13.枚举


笔记小结:



> 
> 1. 含义:它是一种特殊的数据类型,用于定义一组**固定的常量**
> 2. **普通枚举**常量
> 
> 
> 
> ```
> enum Weekday {
>   MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
> }
> 
> ```
> 
> 3. **带**有**参**数的**枚举**常量
> 
> 
> 
> ```
> enum DayOfWeek {
>     MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);
>     private int value;
>     DayOfWeek(int value) {
>         this.value = value;
>     }
>     public int getValue() {
>         return this.value;
> 
> 
> ```
> 
> 4. **实现接口**的**枚举**常量
> 
> 
> 
> ```
> public enum BasicOperation implements Operation {
>     PLUS("+") {
>         public int apply(int x, int y) { return x + y; }
>     }
> 
>     private final String symbol;
> 
>     BasicOperation(String symbol) {
>              this.symbol = symbol;
>     }
> }
> 
> ```
> 
> 5. **匿名内部类**的方式
> 
> 
> 
> ```
> enum Operation {
>     PLUS {
>         public int apply(int x, int y) {
>             return x + y;
>         }
>     }
>     public abstract int apply(int x, int y);
> }
> 
> ```
> 
> 


### 13.1概述


​ Java中枚举是一种特殊的数据类型,用于定义一组**固定的常量**。枚举类型定义了一个枚举集合,可以在其中定义枚举常量,并且可以通过名称来访问它们。枚举在Java中是一个独立的类,可以包含属性、方法和构造函数等元素


​ 枚举常量通常用于表示一组有限的可能取值,例如一周中的星期几、一年中的季节、颜色等等。使用枚举类型可以提高代码的可读性、可维护性和可扩展性


### 13.2基本用例


步骤一:定义枚举


* 创建枚举`Weekday`类



enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}


说明:



> 
> ​ 常量的定义用`,`作为分隔符进行分割
> 
> 
> 


步骤二:演示



// 调用
Weekday today = Weekday.MONDAY;


说明:



> 
> ​ 调用的方式类跟静态常量的调用方法相同
> 
> 
> 


### 13.3枚举常量



/* 格式
enum 枚举名 {
枚举常量1,枚举常量2,……
} */
enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

// 使用
Weekday today = Weekday.MONDAY;
System.out.println(day); // 输出 MONDAY


### 13.4带有参数的枚举常量



/* 格式
enum 枚举名 {
枚举常量1(值),枚举常量2(值),……
} */
enum DayOfWeek {
MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);
private int value;
DayOfWeek(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
// 使用
DayOfWeek day = DayOfWeek.MONDAY;
int value = day.getValue();
System.out.println("Today is " + day + ", value is " + value);// 输出Today is MONDAY, value is 1


### 13.5实现接口的枚举常量



/* 格式
public interface Operation {
int apply(int x, int y);
} */

public enum BasicOperation implements Operation {
PLUS(“+”) {
public int apply(int x, int y) { return x + y; }
},
MINUS(“-”) {
public int apply(int x, int y) { return x - y; }
},
TIMES(“*”) {
public int apply(int x, int y) { return x * y; }
},
DIVIDE(“/”) {
public int apply(int x, int y) { return x / y; }
};

private final String symbol;

BasicOperation(String symbol) {
    this.symbol = symbol;
}

@Override public String toString() {
    return symbol;
}

}

// 使用
int result = BasicOperation.PLUS.apply(1, 2); // 3


### 13.6匿名内部类的方式



// 例如
enum Operation {
PLUS {
public int apply(int x, int y) {
return x + y;
}
},
MINUS {
public int apply(int x, int y) {
return x - y;
}
},
TIMES {
public int apply(int x, int y) {
return x * y;
}
},
DIVIDE {
public int apply(int x, int y) {
return x / y;
}
};

public abstract int apply(int x, int y);

}

// 使用
int result = Operation.PLUS.apply(1, 2) // 返回值为3


## 14.常用类


笔记小结:



> 
> * `String`、`StringBuilder`、`StringJoiner`类,见各个小节
> * 字符串原理:请参见字符串原理小节内容。
> * 注意:不断的使用`String s = “常量”`进行字符串拼接会消耗大量的堆内存空间,**建议使用`StringJoiner`类进行字符串的拼接**
> 
> 
> 


### 14.1String类


笔记小结:



> 
> 1. 概述:Java 程序中所有的**双引号字符串**,**都是 String 类的对象**。String对象**不需要导包**
> 2. 特点:
> 	* **不可变**性:**频繁修改**字符串的操作会**导致内存占用和性能**问题,因为频繁创建String对象并进行重新赋值
> 	* **线程安全**性:多个线程可以同时访问同一个String对象,而**不会**出现**线程安全问题**
> 	* **存储在常量池**中:Java中有一个**字符串常量池**,用于存储字符串常量
> 3. 构造方法
> 	1. String()
> 	2. String(char[] chs)
> 	3. String(byte[] bys)
> 	4. **String s = “常量”**
> 4. 构造方法创建对象与直接赋值区别
> 	1. 创建对象:**不存在复用**,对象每new一次就会在内存中开辟一个新的空间
> 	2. 直接赋值:**存在复用**,若对象的值是常量池中已存在的,则JVM**不会**在堆内存中**开辟**新的**空间**
> 5. 字符串比较
> 	1. == 的作用:**基本**数据**类型**比较**值**,**引用**数据**类型**比较**地址值**
> 	2. **equals**方法的作用:比较**字符串内容**是否相同
> 	3. **equalsIgnoreCase**方法的作用:比较**字符串内容**是否相同,**不区分大小**写
> 6. 案例:
> 	1. 手机号屏蔽:`字符.substring()`
> 	2. 敏感词替换:`字符串.replace()`
> 
> 
> 


#### 14.1.1概述


​ String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,**Java 程序中所有的双引号字符串,都是 String 类的对象**。String 类在 java.lang 包下,所以使用的时候**不需要导包**!


#### 14.1.2特点


* **不可变**性:String对象一旦创建,其内容不可变。这意味着当对一个**String对象**进行**修改**时,**实际上是创建了一个新的String对象**,并将原对象的内容复制到新对象中。因此,频繁修改字符串的操作会导致内存占用和性能问题
* **线程安全**性:由于String对象不可变,所以多个线程可以同时访问同一个String对象,而不会出现线程安全问题
* **存储在常量池**中:Java中有一个字符串常量池,用于**存储字符串常量**。当创建一个字符串时,如果该字符串已经存在于常量池中,则返回常量池中的字符串对象,否则创建一个新的对象并添加到常量池中
* **支持操作符**+和+=:可以通过+和+=操作符将两个字符串连接起来,形成一个新的字符串。但是需要注意的是,**每次使用这些操作符都会创建一个新的String对象**
* 支持**Unicode编码**:String类中的字符编码采用Unicode编码,这使得String可以支持多种语言和字符集
* 支持常用的**字符串操作**:String类提供了许多常用的字符串操作,例如字符串比较、查找、替换、切割、大小写转换等


#### 14.1.3构造方法


* 常用的构造方法



| 方法名 | 说明 |
| --- | --- |
| public String() | 创建一个空白字符串对象,不含有任何内容 |
| public String(char[] chs) | 根据字符数组的内容,来创建字符串对象 |
| public String(byte[] bys) | 根据字节数组的内容,来创建字符串对象 |
| String s = “abc”; | 直接赋值的方式创建字符串对象,内容就是abc |
* 示例代码

 

public class StringDemo01 {
public static void main(String[] args) {
//public String():创建一个空白字符串对象,不含有任何内容
String s1 = new String();
System.out.println(“s1:” + s1);

    //public String(char[] chs):根据字符数组的内容,来创建字符串对象
    char[] chs = {'a', 'b', 'c'};
    String s2 = new String(chs);
    System.out.println("s2:" + s2);

    //public String(byte[] bys):根据字节数组的内容,来创建字符串对象
    byte[] bys = {97, 98, 99};
    String s3 = new String(bys);
    System.out.println("s3:" + s3);

    //String s = “abc”: 直接赋值的方式创建字符串对象,内容就是abc
    String s4 = "abc";
    System.out.println("s4:" + s4);
}

}



说明:



> 
> * **字符**数组常用在更换 某个字符,此时需要构造方法
> * **字节**数组常用在把字节信息进行转换,此时需要构造方法
> 
> 
> 


#### 14.1.4构造和直接赋值方式创建对象区别


* 通过**构造方法**创建

 ​ 通过 new 创建的字符串对象,每一次 **new 都会申请一个内存空间**,虽然内容相同,但是地址值不同

 ![image-20230303094222966](https://img-blog.csdnimg.cn/img_convert/b393ab8090fc864c673f9dbb2f16c7c9.png)


说明:



> 
> ​ 不存在复用,因为每次new出来的对象会在内存中开辟一个新的空间
> 
> 
> 


* 直接**赋值方式**创建

 ​ 以“ ”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护

 ![image-20230303093958531](https://img-blog.csdnimg.cn/img_convert/d3ee27f02a07f320b8eecc1915e1d556.png)


说明:



> 
> ​ 当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。若不存在,则创建新的、若存在则复用
> 
> 
> 


#### 14.1.5字符串的比较


##### 14.1.5.1==号的作用


* 比较**基本数据**类型:比较的是**具体的值**
* 比较**引用数据**类型:比较的是对象**地址值**


##### 14.1.5.2equals方法的作用


* 方法介绍

 

public boolean equals(String s) 比较两个字符串内容是否相同、区分大小写

* 基本用例

 

public class StringDemo02 {
public static void main(String[] args) {
//构造方法的方式得到对象
char[] chs = {‘a’, ‘b’, ‘c’};
String s1 = new String(chs);
String s2 = new String(chs);

    //直接赋值的方式得到对象
    String s3 = "abc";
    String s4 = "abc";

    //比较字符串对象地址是否相同
    System.out.println(s1 == s2); // false
    System.out.println(s1 == s3); // false
    System.out.println(s3 == s4); // true
    System.out.println("--------");

    //比较字符串内容是否相同
    System.out.println(s1.equals(s2)); // true
    System.out.println(s1.equals(s3)); // true
    System.out.println(s3.equals(s4)); // true
}

}



##### 14.1.5.3equalsIgnoreCase方法的作用


​ equalsIgnoreCase 是 Java 中的一个字符串方法,用于比较两个字符串是否相等,但忽略它们的大小写。它与 `equals` 方法类似,但不考虑大小写的区别。


方法介绍:



public boolean equalsIgnoreCase(String anotherString)


#### 14.1.5案例—手机号屏蔽


说明:



> 
> ​ 需求:以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽
> 
> 
> 


代码实现:



public class Test8手机号屏蔽 {
public static void main(String[] args) {
/*以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽
最终效果为:131****9468*/

    //1.键盘录入一个手机号码
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入手机号码");
    String phoneNumber = sc.next();//13112349408

    //2.截取手机号码中的前三位
    String star = phoneNumber.substring(0, 3);

    //3.截取手机号码中的最后四位
    //此时我用substring方法,是用1个参数的,还是两个参数的?1个参数的会更好
    //因为现在我要截取到最后,所以建议使用1个参数的。
    String end = phoneNumber.substring(7);

    //4.拼接
    String result = star + "\*\*\*\*" + end;

    System.out.println(result);

}

}


补充:在 Java 中,`substring` 是字符串类中的一个方法,用于截取一个字符串的子串



> 
> 这个方法有两种不同的用法:
> 
> 
> 1. 截取从指定位置开始到字符串末尾的子串:
> 
>  
> ```
> public String substring(int beginIndex)
> 
> ```
>  其中,`beginIndex` 表示截取子串的起始位置。返回从 `beginIndex` 开始到字符串末尾的子串。
> 
>  例如:
> 
>  
> ```
> rustCopy codeString str = "Hello, world!";
> String substr = str.substring(7);  // 截取 "world!"
> System.out.println(substr);
> 
> ```
>  输出结果为:
> 
>  
> ```
> world!
> 
> ```
> 2. 截取从指定位置开始到指定位置结束的子串:
> 
>  
> ```
> public String substring(int beginIndex, int endIndex)
> 
> ```
>  其中,`beginIndex` 和 `endIndex` 分别表示截取子串的起始位置和结束位置。返回从 `beginIndex` 开始到 `endIndex - 1` 结束的子串。
> 
>  例如:
> 
>  
> ```
> rustCopy codeString str = "Hello, world!";
> String substr = str.substring(7, 12);  // 截取 "world"
> System.out.println(substr);
> 
> ```
>  输出结果为:
> 
>  
> ```
> world
> 
> ```
> 
> 
> ​ 需要注意的是,`substring` 方法返回的是一个新的字符串,而不是在原字符串上进行修改。如果 `beginIndex` 或 `endIndex` 超出了字符串的范围,会抛出 `IndexOutOfBoundsException` 异常。
> 
> 
> 


#### 14.1.6案例—敏感词替换


需求1:键盘录入一个 字符串,如果字符串中包含(TMD),则使用\*\*\*替换



public class Test9敏感词替换 {
public static void main(String[] args) {
//1.定义一个变量表示骂人的话
String talk = “后裔你玩什么啊,TMD”;

    //2.把这句话中的敏感词进行替换
    String result = talk.replace("TMD", "\*\*\*");

    //3.打印
    System.out.println(talk);
    System.out.println(result);
}

}


需求2:如果要替换的敏感词比较多怎么办?



public class Test10多个敏感词替换 {
public static void main(String[] args) {
//实际开发中,敏感词会有很多很多

    //1.先键盘录入要说的话
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入要说的话");
    String talk = sc.next();//后裔你玩什么啊,TMD,GDX,ctmd,ZZ

    //2.定义一个数组用来存多个敏感词
    String[] arr = {"TMD","GDX","ctmd","ZZ","lj","FW","nt"};

    //3.把说的话中所有的敏感词都替换为\*\*\*

    for (int i = 0; i < arr.length; i++) {
        //i 索引
        //arr[i] 元素 --- 敏感词
        talk = talk.replace(arr[i],"\*\*\*");
    }

    //4.打印结果
    System.out.println(talk);//后裔你玩什么啊,\*\*\*,\*\*\*,\*\*\*,\*\*\*

}

}


补充:在 Java 中,`replace` 是字符串类中的一个方法,用于替换一个字符串中的某些字符或子串。\*\*\*\*



> 
> 这个方法有两种不同的用法:
> 
> 
> 1. 用新的字符串替换掉所有的旧字符串:
> 
>  
> ```
>  public String replace(CharSequence target, CharSequence replacement)
> 
> ``	
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值