学习日志_04 面向对象

1.面向对象

1.1.概述

面向对象:面向对象是软件开发方法,一种编程范式,面向对象的概念和应用已超越程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段的产物。

面向对象是相对于面向过程来说的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统的建模,更贴近事物的自然运行模式。

Java特性:跨平台,多线程,自动垃圾回收,面向对象

面向对象特性:封装,继承,多态,抽象。

1.2.面向对象和面向过程

面向对象侧重分模块

在编程思想方面是以对象为核心,将问题分解成不同对象,每个对象都有其属性和行为,通过对象之间的交互来解决问题

在数据处理与控制方式上,面向对象的数据与操作封装成一个对象,其他对象不能直接修改其数据,只能通过对象的set或者get函数来操作。控制程序的方式是通过”事件驱动“来激活和运行程序。

在模块化与复用上,面向对象通过类和继承来实现模块化,提高了代码的可重用性和可维护性。

封装、继承和多态都是面向对象特有的 特性。

在软件开发的视角

面向对象更注重于问题的整体解决方案和对象的交互,适合于大型、复杂的系统开发。

面向过程侧重分步骤

在编程思想方面以过程为核心,强调问题分解成一系列的步骤或者函数,然后按照顺序调用这些函数来解决问题。

在数据处理与控制方式上,面向过程的数据与代码是分离的,数据通过函数或者过程来处理,处理完毕后显示结果。控制程序的方式是按照设计调用或者返回程序。

在模块化与复用上,面向过程在模块化实现上使用子程序或者过程,便于开发和维护,但可重用性差,数据安全性差。

在软件开发的视角,面向过程更注重于过程的实现和流程的清晰性,适合于小型项目或者简单的任务。

1.3.构造方法

构造方法:用于创建对象并对数据初始化。

语法:权限修饰符 类名 (参数列表){方法体}

构造方法的方法名必须和类名一致,构造方法没有返回值,连void都没有

如果没有编写构造方法,则默认有一个公共的无参构造方法 

如果我们编写了任意构造方法,不论是否是有参构造方法,都不会在有默认的无参构造了

所以一般我们编写有参构造的时候,会再写一个无参构造

1.4.类和对象

类:把具有相同”特征“的事务进行分类,代码中:根据具体事务或者需求进行特征的抽象,进行描述汇总,是我们描述客观事物的一个标准,一个模板

对象:对象是一个类中具体的个体,比如有一个学生类,里面记录着成员变量姓名 name ,年龄age等,还有他的构造方法,我们通过构造函数生成一个对象(张三,18),生成的数据就是对象。

类只是属性的封装描述,对象是对属性进行赋值存储。

根据不同的特征/属性划分成不同的类,根据不同的属性值,划分不同的对象

同类的多个对象,一定具有相同的特征

1.5.对象使用

对于属性没有private权限修饰符的数据,我们可以直接用  对象.属性  直接修改其数据。但是大部分应该将属性private私密起来,通过set,get方法获取和修改其中的属性。

1.6.Bean

JavaBean是一个实体类,类必须是具体的,公共的,并且具有无参构造器。JavaBean中的属性需要用private修饰,并且具有set和get方法,以及构造器。

1.7实例化

语法: 引用类型 变量名 = new 引用类型(参数);

第一步:静态加载:运行时会把所有相关的类全部加载到左边的静态区

动态加载:运行时,只加载当前类,当用到其它类的时候再去加载

Java中采用的动态加载:

实例化:

1.加载类到静态区

2. new 在堆内存中创建内存空间

3.执行构造方法对对象中数据进行初始化赋值

4构造方法弹栈,返回堆内存地址。

1.8.常见异常

空指针异常:

类是引用数据类型,所以在创建对象时,对象的数据类型是引用数据类型,所以对象存储的是地址,所有引用数据类型都可以赋值null,引用数据类型默认值为null。但是对象为null之后不在指向堆内存对象数据,就会丢失对象数据。此时在用null的对象访问成员属性,就会报空指针异常。

1.9.对象调用静态属性

在对象中设置成员属性的修饰符 为静态时,即使对象是空指针也不会影响该属性的调用,因为在编译时,会自动将对象、属性 转化成 类名、属性  (这里防止看不清楚,我用、代替小数点.,编译时要用小数点.);

1.10.注释事项

1.10.1.静态调用成员

Java中静态上下文中无法引用非静态变量:

non-static variable mainframe cannot be referenced from a static context 

非静态的成员变量是一个对象属性,只有在对象存在时才可以引用。因此,如果在对象未创建实例时,在静态方法中调用了非静态成员方法是非法的。静态方法可以不用创建对象就调用,非静态方法必须有了实例对象才能调用。因此在静态方法中引用非静态方法是不可能的。

具体了解可以去下面这个博主发的文章里了解,有截图有举例。
该播主链接:https://blog.csdn.net/u014663877/article/details/84861362

1.10.2 区分成员方法和构造方法

1.构造方法的方法名必须与类名一致,成员方法的方法名可以与类名一致,当成员方法的方法名与类名一致时要看返回值区分,构造方法是没有返回值的,连void都没有,成员方法必有返回值。

2.This

2.1概述

this:是每个对象中第一个成员变量,用于保存当前对象的内存地址

this只能出现在构造方法和成员方法中,不能在静态上下文中使用

2.2作用在哪

1.在成员方法或者构造方法中,用于区分同名的成员变量或者局部变量

2.用在构造方法中,用于重载调用构造方法,必须在构造方法的有效代码的第一行

比如存在如下两个构造方法,一个无参构造,一个有参构造,在无参构造中可以使用this调用其他的构造方法,实现所有的对象的初始化。

3.返回的this可以链式调用

2.3用法

1.区分成员和局部:成员和局部同名时,this指的是调用该方法的对象,编写方法时传入的值的名字与成员变量相同时,使用this来区分成员和局部。

2.重载调用构造方法,同上图,用于重载调用构造方法时,必须放在构造方法第一行。

3.链式调用:目的是前者方法的返回值能够调用后者方法的对象,下图中Test02 t2 = t1.m1();

等价于Test02 t2 = t1;

2.4.注意事项

this只能出现在构造方法和成员方法中,不能再静态上下文中使用

原因:静态方法与类相关联,而this与实例对象相关联,意味着,即使一个类没有调用构造方法或者实例化任何对象,静态方法依然可以通过类名调用,而这时如果有this,this只能指向类,这在Java中是不允许的,所以静态上下文中不能有this

3.Static

static是修饰符,用于修饰静态数据。

1.static修饰的变量,方法,和语句块分别是静态变量、静态方法、静态语句块。

3.1静态语句块

静态语句块可以看成没有语句块的静态方法,不能调用,在类加载阶段会自动执行,是最先执行的语句并且只执行一次(main方法之前),因此静态语句块适合初始化操作(如果需要在main方法中使用初始化的数据,最好在静态语句块之前先静态声明出来)。当访问一个类的静态属性时,才会加载这个类。

3.2实例语句块

实例语句块可以看作没有名字的成员方法

每次创建一个对象就执行一次,并且在构造方法之前执行。

4.封装

4.1包的机制

4.1.1.package

package:解决命名冲突问题,在文件名前,加上命名空间(前缀)

package限制的是class文件的保存目录,和java文件无关

命名规则一般采用公司域名倒叙

例如河北地质大学 :  com.HebeiGEO.www

cn.edu.hgu.www

4.1.2.Import

 同目录(同包)下,可以直接写名字使用

Package_01 p = new Package_01();

不同目录下,需要写全名,格式是包名.类名

如果当前的类用到了其他包内的类,可以通过import 导入用到的类。

可以导入多个类,如果某一个包内大多数的类都会用到,可以导入时用包名.*代替包名.某一个类

java.lang.*下所有类都是核心类,可以直接使用不需要导入

注:impor语句在编译工具中一般不需要我们手动导入,在编译中一般按回车或者空格会自动导入,但是需要注意可能会导错包。

静态导入:使用一个类的静态变量时候,需要加类名.静态变量名

静态导入后,,可以在当前类中直接写变量名使用,不需要加类名,不过不建议这样写,小规模无所谓,大项目变量多容易重名

4 .2. 权限控制

上图摘自网络(水印是自动加上去删不掉)

权限控制修饰符要根据数据被使用情况而定

1.private 私有的,除了自己类中的,其他都不能访问,一般用于保护数据,类中会设有get、set方法调用私有的属性

2.default 默认修饰符,不写修饰符时就是包权限,在同一个包中的类都可以调用,其他包调用需要修改修饰符为public公共的,如果保持default,即使导入包也不能直接访问。

3.protected 是受保护的修饰符,在同一包中的其他类或其子类都可以直接访问数据,这里的子类不单单是继承于含有受保护属性的类,包内的所有类的子类都可以直接访问数据。

4.public 公共的修饰符。权限最高,项目中哪里的数据都能访问。

5.继承

5.1继承是什么

继承就是从已有的类中派生出新的类,新的类中包含父类的属性和行为

在新的类中 ,还能扩展新的属性和行为

在Java中,类只有单继承,一个类只能继承一个父类,继承关系是可以传递的,就是孙子可以继承爷爷的属性和行为,但是不能环形继承(即其中某一个子类成为这条继承线的父类)

私有化属性是不能被继承的,但是可以通过父类提供的get方法进行访问

如果没有显示继承其他类,则默认继承java.lang.Object类,Object是Java提供的根类(所有类的祖宗)

5.2.继承的作用

继承目的是实现代码的复用,最核心的实现方法就是方法覆写Override(这里不同于方法重载)

方法重载是相同方法名,不同的返回值类型,不同的参数类型,相同功能

方法覆写是相同的方法名,相同的返回值类型,相同的参数类型,不同的功能

5.3.继承的使用

class A{

}

class B extends A{

}

6.Super

6.1.Super是什么

super官方解释是:super保存了父类型特征

可以理解为子类中super代表父类

6.2.能做什么

可以用在成员方法/构造方法中,用于区分父类和子类同名的属性

可以用在子类构造方法中,调用父类构造方法,如super(参数);改写法必须在子类的构造方法的第一行,所以super(参数)和this(参数)无法同时出现

如果构造方法中,没有出现this(参数)和super(参数),则默认有一个super()去调用父类的无参构造

6.3.怎么用

可以用在成员方法/构造方法中,区分子类与父类同名属性:

可以用在子类构造方法中,调用父类构造方法:

运行结果与上图无异;

当调用父类的有参构造时,父类中this指向的时父类的age,修改的是父类的age,在子类构造时如果没有显式调用父类的构造方法,则会默认调用父类的无参构造方法。因此子类构造无论如何都会调用父类的构造方法,这里就算用this调用子类的其他构造方法,该方法也会去调用父类构造,拦不住的~!

6.4.注意

1 this和super都不能出现在静态上下文中,因为this和super都是引用类型,有指向目标(this一般指向对象或者子类,super一般指向父类),在静态上下文中,静态能够无对象直接类名加点来调用,这时this和super无意义,必然报错。

6.5.实例语句块和构造方法

想要加载一个类必须先加载对应的父类,因为子类需要拥有父类属性

因此当父类子类中都有 静态语句块,实例语句块,构造方法时,运行结果,创建子类对象运行结果必然是父类静态(先加载),子类静态(第二加载),父类实例(super先运行父类,实例语句块在构造方法之前),父类构造(super运行父类构造器),子类实例(super执行完之后,运行)子类构造

注意:实例对象是在构造方法执行中创建,这里的父类构造是构造方法即将结束时才输出,因为super必须在有效代码的第一句,因此无论怎么写,这个输出都在构造方法快结束时才会执行,在这之前,对象实例已经被创建,实例语句块执行,先构造方法结束一步输出。子类同理。

7.覆写Override

7.1.覆写是什么

Override方法覆写就是对继承父类的方法进行重写

覆写条件:

1.在有继承关系的体系中

2.方法名,参数列表,返回值必须一致

3.不能比原方法拥有更低的访问权限

4.不能比原方法有更宽泛的异常

5.方法覆写特指成员方法,与其他无关

7.2.应用场景

当父类无法满足当前子类需求的时候,子类根据需求对父类方法重写:

比如父类中方法是输出“父类的年龄”,这时候创建的子类对象使用这个方法肯定是不合理的,因此需要对这个方法覆写,方法体改成输出“子类的年龄”。

7.3.面试题

Override 和 Overload的区别

Override 是方法覆写,当父类功能无法满足子类的需求时,子类需要根据需求对父类方法进行重写,需要注意的是,覆写后的方法,方法名,返回值,参数列表,必须和原方法一致,不能有更低的访问权限,不能有更宽泛的异常

Overload时方法重载,指的是在同一个类里,方法名相同,参数列表不同的情况

作用是相同的功能,设置相同的方法面,更容易记忆,更容易记忆。

8.Final

8.1.final是什么

final是修饰符,表示最终的,无法更改的

8.2.final能做什么

final修饰的类,不能继承

final修饰的成员方法不能被覆写

final修饰的局部变量不能二次赋值

final修饰的成员变量,不能被二次赋值,没有默认值,必须显示赋值(因此,final修饰必然有值)

final修饰的静态变量,我们称为常量,常量一般使用public static final 修饰,不能被二次赋值。

8.3.final怎么用

成员变量(类下的变量):final 修饰的成员变量必须显示赋值

静态变量(用static修饰的成员变量,但是该变量属于类而不是对象实例,不能在方法中和类外存在):final修饰的静态变量就是常量

局部变量(方法内的变量):final修饰的局部变量不能二次赋值

类:final修饰的类没有子类,无法被继承

方法:final修饰的方法,无法被覆写

8.4.深入final

  1. Final 变量: 声明的变量只能被赋值一次,之后不能再改变其值。这在确保变量值不被修改或被意外改变时非常有用。

  2. Final 方法: 声明的方法不能被子类重写或覆盖。这通常在你确定一个方法不需要被修改或者子类化时使用。

  3. Final 类: 声明的类不能被其他类继承。这意味着该类的行为不能被改变或扩展。Final 类通常是为了安全性或者效率而设计的,因为它们的行为不会受到子类的影响。

  4. Final 参数: 在方法参数中使用 “final” 关键字表示该参数在方法内部不可修改。

  5. Final 数组: 声明的数组引用不能被改变,但是数组中的元素可以被修改。这意味着你不能再将该引用指向另一个数组,但是可以修改数组中的内容。

由上,final修饰的基本类型一旦赋值不能再改变,final修饰的数组其内的值可以被改变,但是其地址不能改变。使用 final 关键字修饰的类表示该类是最终的,不能被其他类继承。这意味着即使子类想要覆写父类的方法,也是不允许的。虽然父类的地址不会变,但是通过将类声明为 final,可以确保类的行为和实现不会被修改或扩展,从而提高代码的稳定性和安全性。

final运行原理如下:

final修饰的数组,固定的是数组的引用,其内的值保存在堆内存,可以对其内的值进行修改

9.多态

9.1.多态的设计原则

多态是面向对象编程的一个重要概念,它允许不同种类的对象对同一消息做出响应。多态的设计原则包括:

  1. 接口隔离原则: 通过接口或抽象类来定义公共的接口,减少对具体实现的依赖,使得不同的实现可以独立变化。

  2. 开闭原则: 多态允许在不修改已有代码的情况下,对程序进行扩展或修改。

  3. 单一职责原则: 每个类或接口都应该保持单一的职责,避免在设计中引入不必要的复杂性。

  4. 依赖倒置原则: 高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖细节;细节应该依赖抽象。

  5. 里氏代换原则: 任何基类可以出现的地方,子类都可以出现,子类可以扩展父类的功能,但不能改变父类原有的功能。

  6. 合成复用原则: 尽量使用对象组合而不是继承关系来实现代码复用,这样可以减少代码间的耦合。

  7. 最少知识原则: 一个对象应该尽可能少地与其他对象发生相互作用,通过接口或抽象类来减少相互之间的依赖。

在设计多态时,应该遵循以上原则,这样可以使得程序更加灵活、易于维护和扩展。

9.2.多态是什么

Java有两种多态机制

1.编译时多态 编译时多态是静态的,主要指的是方法重载,可以根据参数不同,来区分不同的方法,不同的功能。

2.运行时多态 运行时多态是动态的,主要指动态绑定来实现,主要靠父子类实现

多态是里氏替换原则的一种体现,父类引用指向子类对象

父类引用:使用父类类型创建的引用类型变量

指向:可以找到谁

子类对象:子类创建的实例化对象

父类类型创建的变量 保存了  子类对象

9.3.多态怎么用

语法结构:

父类 变量名 = new 子类(); 不一定是直接子类,只要是长辈都可以

输出结果为狗吃肉。一个动物吃东西的方法有很多种方式,每一个物种都有一个特定的方式,使用多态可以优化main方法中代码的可读性和冗杂。

9.4.应用场景和优点

优点:降低类直接的耦合度,降低需求变动带来的代码修改的风险

应用场景:当一个需求对应多种不同实现的时候,一定要使用多态

如果一个事物只有一种可能,就没必要多态了。

9.5.缺点

会丢失子类特有的属性:当父类不存在的属性或方法,子类存在时会报错

9.6.多态进行属性调用

多态缺点:丢失子类的特有的属性(父类没有子类有,就是特有)

多态进行属性调用:

1.父类没有,子类有,报错,不能访问,丢失子类的特有属性

2.父类没有,子类没有,报错,都没有没办法访问

3.父类有,子类没有,执行父类

4.父类有,子类有,成员方法执行子类,其他执行父类

9.7.Instanceof 

作用:判断某个对象是否由某个实例化而来,从而降低类型转换异常的风险(多态可以向下转型)

在Java中,instanceof 是一个用于判断一个对象是否是特定类或接口的实例的关键字。它的语法形式为 object instanceof Class,其中 object 是要判断的对象,Class 是要检查是否为其实例的类或接口。

如果 object 是一个 Class 的实例,或者是 Class 的子类的实例,则返回 true;否则返回 false。这可以用来在运行时判断一个对象的具体类型,以决定如何处理这个对象。

示例:

class Animal {}
class Dog extends Animal {}

Animal a = new Dog();
if (a instanceof Dog) {
    System.out.println("a is an instance of Dog");
} else {
    System.out.println("a is not an instance of Dog");
}

在上面的示例中,a 是 Animal 类的实例,但由于其实际类型是 Dog 类,因此 instanceof 判断为 true

9.8.多态的几种形式

只要最终父类保存了子类对象,都是多态。

1.直接多态:Animal  a = new Dog();

2.形参实参多态: 一个方法的参数列表是父类 声明,但是方法调用时传入 子类对象

3.返回值多态 :返回值是父类类型,但是返回数据时,返回了子类的对象

4.隐式多态 : 通过子类调用父类方法的时候,父类的这个方法中的上下文环境,就会发生多态(父类空间,子类对象)

10.抽象

10.1.抽象概述

abstract 修饰符,表示抽象的

修饰的类 是抽象类,抽象类不能创建对象 (专门用来被继承的)

修饰的方法 是抽象方法,抽象方法没有方法体(专门用来覆写的,抽象方法只存在在抽象类中)

抽象方法必须在抽象类中,而抽象类中,可以没有抽象方法

抽象类往往用来表示设计中得出的抽象概念:比如,动物类,自然界没有一个种族叫做动物,不能代表实体,这个时候我们称这个类为抽象类

抽象类中往往是对事务的属性和行为进行封装,但是不会有实现,一般是用于子类覆写实现

10.2.抽象怎么用

根据概述:抽象类里可以写抽象方法(抽象方法没有方法体),有构造方法(但不能创建对象),功能的实现靠子类

10.3.注意

注意:

1.一个类继承了一个抽象类,需要实现所有的抽象方法

2.一个抽象类继承了一个抽象类,可以实现了0~N个抽象方法

3.abstract 和final 不能同时出现

4.抽象类不能创建创建对象,但是有构造方法,用于子类实例化调用

11.接口

11.1.接口是什么

接口:是引用类型,并且接口可以发生多态

接口可以看做是一个特殊的类,完全抽象,是Java为了解决单继承功能变弱的问题

Java1.8之前:接口完全抽象,只有抽象方法和常量,

Java1.8之后:可以有默认方法和静态方法

接口定义由class变成interface:public interface 接口名{}

接口中没有变量,只有常量{public static final},并且psf可以省略

接口中没有成员方法,只有抽象方法,并且abstract可以省略,public也可以省略

接口和接口之间是多继承,多个使用逗号隔开interface接口名extends父接口1,父接口2,。。。{}

类和接口之间是多实现,使用implements表示,多个逗号隔开,如果需要继承 则必须先继承后实现。

一个类实现一个接口的时候,需要实现所有的抽象方法

接口不能创建对象,并且没有构造方法(因为子类创建对象时调用的父类的构造方法,并不会调用父接口的构造方法,所以接口不需要有构造方法)

抽象类和接口都能完成某个功能时,优先使用接口,保留类继承(因为类之间是单继承,而类和接口是多实现)

11.2.优点

接口可以发生多态,如果一个类没有继承只有实现,则该子类调用的父类构造是隐式父类object的构造方法

类和接口多实现

接口的使用思想是实现多态和解耦,面向接口编程,降低类之间耦合度

11.3.接口怎么用

11.4.接口和抽象类的区别

接口,之间多继承,逗号隔开,类和接口多实现,逗号隔开,接口没有构造方法,不能创建对象

抽象,类与抽象类之间单继承,抽象类有构造方法,但是不能创建对象

接口中只有常量,静态常量,抽象方法,静态方法,默认方法,一个类实现一个或多个接口,需要实现所有抽象方法,一个抽象类实现一个或多个接口,可以实现0~N个抽象方法

抽象中相比普通类,可以有抽象方法,但是抽象方法子类需要全部实现,一个抽象类继承一个抽象类,可以实现0~N个抽象方法

当抽象类和接口都能完成某个功能的时候,优先使用接口,这样能够保留类的继承

12.object

12.1.toString

toString方法的设计目的是返回该对象的字符串表示形式,结构为包名和类名 + @ +十六进制的hash值

当打印一个引用类型的时候,会自动调用该对象的toString方法(隐式调用)

默认的toString方法,返回十六进制整型值(一般称为内存地址)

如果不需要打印内存地址,则需要我们根据需求进行重写

12.2.Equals

==比较基本类型的时候,比较的是值的大小,而比较引用类型的时候,比较的是内存地址

equals方法的设计目的:比较两个对象是否相同

使用Object中的equals方法和使用==没有区别。

new 的两个对象,地址一定不一样,我们比较不会去比较地址,而是比较其保存的属性是否一致

而Object中的equals方法,默认比较的也是内存地址,所以需要根据需求进行重写

重写前:重写后:

12.3.Finalize

finalize是Java中的一个方法,用于在对象被垃圾回收之前执行一些清理操作。当Java虚拟机确定不再有任何对对象的引用时,即将回收该对象时,会调用其finalize方法。

JVM四大特性:跨平台,自动垃圾回收,面向对象,多线程

所谓回收,就是把该对象在内存中删除,该对象的生命周期也到此结束

finalize方法是对象生命周期中,最后做的事,所以一般适合做一些关闭和销毁资源等操作

垃圾:当一个对象没有任何引用可以指向它的时候,这个对象就被视为垃圾对象

finalize方法不需要手动调用,该方法并没有垃圾回收的功能,如果手动调用也仅仅是方法调用而已。但是可以用System.gc()建议垃圾回收机制进行垃圾回收,垃圾过多的时候不用建议也会回收

13.类关系

继承:类和类是单继承,接口和接口是多继承,多个使用逗号隔开

实现:类和接口是多实现,多个使用逗号隔开

关联:关系性比较强,一般是某个类的成员变量保存了另一个类的引用

依赖:关系性较弱,一般是某个局部变量,保存了另一个类的引用

组合:各自不具备独立的生命周期,需要依赖于整体,生命周期相绑定

聚合:各自具有独立的生命周期,不需要依赖于整体,生命周期不稳定

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值