C#OOP基础知识

1:变量

变量概述

由于变量让你能够把程序中准备使用的每一段数据都赋给一个简短、易于记忆的名字,因此它们十分有用。变量可以保存程序运行时用户输入的数据(如使用Console.RedLine()方法在控制台上显示一个冒号,然后把用户键入的文本保存到变量中)、特定运算的结果以及要在窗体上显示的一段数据等。简而言之,变量是用于跟踪几乎所有类型信息的简单工具。

变量声明后没有赋值的话,编译器会自动提示并赋予默认值。

变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存储Script运行时可更改的程序信息。例如,可以创建一个名为Click Count的变量来存储用户单击Web页面上某个对象的次数。使用变量并不需要了解变量在计算机内存中的地址,只要通过变量名引用变量就可以查看或更改变量的值。在VB Script中只有一个基本数据类型,即Variant,因此所有变量的数据类型都是Variant。 

变量命名

 

变量名的第一个字符必须是字母、下划线或@;
    其后的字符可以是字母、下划线或数字;
    变量名区分大小写;
    不能使用C#关键字作为变量名,如 int、double、char、namespace等;


声明变量

 //格式:变量类型 变量名称;
int num;
bool isGood;
char character; 
//变量在使用前必须初始化,否则无法通过编译num = 1;
isGood = true;character = 'A'; //也可以在声明变量时初始化
int num  = 1;
bool isGood = true;
char character = 'A'; //一次声明多个相同类型的变量,以“,”分隔各个变量
int num1, num2;
bool isGood, isBad;
char char1, char2; //同时使用以上各种技巧
int num1 = 1, num2 = 2;
bool isGood, isBad = false;     //isGood没有初始化
isGood = true;                  //初始化isGood

2:数组

数组的定义

1、数组的长度是固定

2、是同一个类型的数据

3、根据索引index来查找,第一个0开始

数据分为 一维数组、二位数组、数组的数组

//一维数组: int[] number =new int[5];//表示定义一个长度为5 的一维数组 //
赋值: int[] number2=new int[5] {1,2,3,4,5};
 int[] number2=new int[] {1,2,3,4,5}; 
int[] number2={1,2,3,4,5}; 
//二位数组: string[,] name=new string[2,2];//
表示定义一个一维长度为5二维长度为4 的二维数组 
//赋值: string[,] name2={{"a","b"},{"c","d"}};
 //数组的数组: int[][] scores=new int[2][];
//表示定义一个一维长度为2,二维长度不固定的数组  
//赋值: int scores2={new int[]{1,2,3},new int[] {4,5,6,7,8}};

3:循环

循环的定义

1.使用循环的原因

当同一性质的的判断或事件,相继出现,一个一个的书写不但麻烦,还增加代码量不便于存储,这个时候就需要用到循环啦,帮助我们更好的实现想要实现的问题,简单易懂;

2.循环是什么?

循环是程序中重复执行,直到满足指定条件才停止的一段代码。在编码过程中也用到了关系和逻辑运算符。

3.C#常见的循环结构

  • while循环
  • do-while循环
  • for循环
  • foreach循环

4.循环的应用

  • While 循环

  先判断,然后再执行循环体;试用与不知道循环次数;

//用while continue实现计算1-100之间含100的除了能被七整除之外的所有整数之和             
int i = 0;                   
int sum = 0;                 
while (i <100)       //判断    {
         i++;         
if (i % 7 == 0)    {         
continue;        //暂停当前循环运行,然后再继续,本练习中则是结束i%7==0,这个整除的循环,    }                    //不进行输出,那么所有输出的就是整除之外的所有整数    
sum += i;    }    
Console.WriteLine("总和为{0}", sum);    
Console.ReadKey();
  • break与continue

  break是结束整个循环体,continue是结束单次循环;

for (; i < 5; i++)  {     
Console.WriteLine("请输入年龄");     
int age = int.Parse(Console.ReadLine());     
if (age <=0 || age > 100)     {         
break;                 //当输入年龄满足上面的条件语句时,那么整个循环过程也就结束,不再继续执行     }        
sumAge += age;   }
  • do-while循环

  先执行循环体,然后再进行判断;试用与不知道循环次数;

string str = "";     
int number = 0;     
do     {     Console.WriteLine("请输入一个数");     
str = Console.ReadLine();               //循环体执行     
if (str != "q")                         //判断         {              
number = Convert.ToInt32(str);              
Console.WriteLine(number * 2);         
}      
} while (str!="q");  
Console.WriteLine("程序结束");  
Console.ReadKey();
  • for循环

  for循环是一个允许我们设定一个执行特定次数循环的重复控制结构,也就是说我们已经提前知道循环次数,那么可以用for,较方便;

for (int i = 0; i < 100; i++)
      {
      Console.WriteLine("123456");
      }
  Console.ReadKey();


  • foreach循环

  使用foreach可以迭代数组或者一个集合对象,为数组或对象集合中的每个元素重复一个嵌入语句组,用于循环访问集合以获取所需信息,也就是遍历的一个过程;

int[] mouth = new int[] { 0, 1, 1, 2, 3, 5, 6, };
foreach (int tooth in mouth){    System.Console.WriteLine(tooth);
}
System.Console.WriteLine();    //输出即为0, 1, 1, 2, 3, 5, 6,
System.Console.ReadKey();

4:C#数据类型

1.值类型

在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。
值类型(value type):byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。值类型变量声明后,不管是否已经赋值,编译器为其分配内存。

 


int num1 = 0;
int num2 = num1;


2.引用类型

引用类型(reference type):string 和 class统称为引用类型。当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
 


string name1 = "name";
string name2 = name1;


5:集合

C#中的四种集合

(1)ArrayList

ArrayList类似于数组,有人也称它为数组列表。ArrayList可以动态维护,而数组的容量是固定的。
它的索引会根据程序的扩展而重新进行分配和调整。和数组类似,它所存储的数据称为元素,它所保存的元素数就是它的容量。默认初始容量为0,在使用它时,需引入命名空间System.Connections;以下代码可以定义一个ArrayList:

using System.Collections;

//创建容量为0的ArrayList对象

ArrayList myList = new ArrayList();

//创建容量为5的ArrayList对象

ArrayList myList = new ArrayList(5);

//获取对象中实际包含的元素数

int num = myList.Count();

ArrayList通过Add()方法添加元素,其方法返回一个Int类型的值,这个值代表所添加的元素在集合中的索引。

参数:如果向ArrayList中添加的元素是值类型,那么这些元素就会自动装箱处理转换为Object引用类型,然后保存,所以ArrayList中的所有元素都是对象的引用。

删除ArrayList中的元素有三种方法,分别为:

对象名.RomoveAt(int index);

对象名.Romove(Object value);

对象名.Clear();(这种方法会将集合中的所有元素删除,俗称"清空"~~~)

(2)HashTable

C# /提供了一种称为HashTable的数据结构,通常称为哈希表,有的人称它为"字典".HashTable的数据是通过键(Key)和值(Value)来组织的,同ArrayList一样,它也属于System.Collections命名空间中,它所存放的每个元素都是键/值对.以下为HashTable的常用方法和属性:

属性名称:Count

属性名称:Keys

属性名称:Values 说明: 获取包含在HashTable中值的集合

方法名称:Add(Object key,Object Value)

方法名称:Remove(Object Key)

方法名称:Clear()

和ArrayList不同,访问HashTable元素时可以直接通过键名来获取具体值,同样,由于值类型是Object.所以当得到一个值时也需要通过类型转换得到指定类型的对象.

(3)泛型集合: List

泛型是C#2.0中的一个新特性。泛型引入了一个新概念:类型参数。通过使用类型参数(T),减少了运行时强制转换成装箱操作的风险。通过泛型集合可以最大限度的重用代码、保护类型的安全及提高性能。

定义一个 List泛型集合的方法如下:

List 对象名 = new List();

List添加元素、获取元素、删除元素以及遍历和ArrayList用法都是类似的,但 List保障了类型的安全性。在获取元素时无需进行类型转换.下面我们把List和ArrayList作以比较

不用点:List对所保存元素做类型约束,而ArrayList可以增加任意类型。添加、读取值类型元素 List无需拆箱装箱,而ArrayList需要做拆箱、装箱处理。

相同点:通过索引访问集合中的元素,添加、删除元素方法相同

(4)泛型集合Dictionary<K,V>

它具有泛型的全部特性,编译时检查类型约束,获取元素时无需类型转换,并且它存储数据的方式和HashTable类似。也是通过Key/Value对元素保存的。定义语法为:

Dictionary<K,V>对象名 = new Dictionary<K,V>

<K,V>中的K表示集合中Key的类型,V表示Value的类型,它的含义和List是相同的.例如:

Dictionary<string,SE> engineers = new Dictionary<string,SE>();

在这个集合中,Key类型是string类型,Value是SE类型。 下面我们把 Dictionary<K,V> 和HashTable作以比较:

不同点: Dictionary<K,V>对所保存的元素做类型约束,而HashTable可以增加任何类型。 Dictionary<K,V>添加、读取值类型元素无需拆箱、装箱,而HashTable需要做拆箱、装箱处理

相同点:通过Key获取Value, 添加、删除、遍历元素方法相同

6:类的方法

方法

“方法”是包含一系列语句的代码块。在 C# 中,每个执行指令都是在方法的上下文中完成的。

方法在类或结构中声明,声明时,声明时需要指定访问级别、返回值、方法名称以及任何方法参数。方法参数放在括号中,并用逗号隔开。空括号表示方法不需要参数。下面的类包含五个方法:
 

class Test{
    void Method1() {
 }                      //无返回值、无参数的方法    
void Method2(int i) { 
}                 //无返回值、有一个参数的方法    
int Method3(bool b, string s) { 
}       //返回值为int、有二个参数的方法    class class1 { 
}                        //定义一个类作为参数或者返回值    
class1 Method4(float f, class1 c) { 
}   //返回值为class、有二个参数的方法}

7:继承

继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。

当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。

继承的思想实现了 属于(IS-A) 关系。例如,哺乳动物 属于(IS-A) 动物,狗 属于(IS-A) 哺乳动物,因此狗 属于(IS-A) 动物。

基类和派生类

一个类可以派生自多个类或接口,这意味着它可以从多个基类或接口继承数据和函数。

C# 中创建派生类的语法如下:
 

<访问修饰符符> class <基类>
{
 ...
}
class <派生类> : <基类>
{
 ...
}


假设,有一个基类 Shape,它的派生类是 Rectangle:

using System;
namespace InheritanceApplication{   
class Shape    {      
public void setWidth(int w)      {         
width = w;      
}      public void setHeight(int h)      {
         height = h;      
}      
protected int width;      
protected int height;   
}   
 // 派生类   class Rectangle: Shape   {      
public int getArea()      {          
return (width * height);       
}   
}     
 class RectangleTester   {      
static void Main(string[] args)      {         
Rectangle Rect = new Rectangle();          
Rect.setWidth(5);         
Rect.setHeight(7);          // 打印对象的面积         
Console.WriteLine("总面积: {0}",  Rect.getArea());         
Console.ReadKey();      
}   
}
}

当上面的代码被编译和执行时,它会产生下列结果:

总面积:35

基类的初始化

派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。您可以在成员初始化列表中进行父类的初始化。

下面的代码演示了这点:

using System;
namespace RectangleApplication{   
class Rectangle   {      
// 成员变量      protected double length;
      protected double width;      
public Rectangle(double l, double w)      {         
length = l;         
width = w;      
}      
public double GetArea()      {         
return length * width;      
}      
public void Display()      {         
Console.WriteLine("长度: {0}", length);         
Console.WriteLine("宽度: {0}", width);         
Console.WriteLine("面积: {0}", GetArea());      
}   
}//end class Rectangle     
class Tabletop : Rectangle   {      
private double cost;      
public Tabletop(double l, double w) : base(l, w)      { 
}      
public double GetCost()      {         
double cost;         
cost = GetArea() * 70;         
return cost;      
}      
public void Display()      {
         base.Display();         
Console.WriteLine("成本: {0}", GetCost());      
}   
}   
class ExecuteRectangle   {      
static void Main(string[] args)      {         
Tabletop t = new Tabletop(4.5, 7.5);         
t.Display();         
Console.ReadLine();      
}   
}
}

当上面的代码被编译和执行时,它会产生下列结果:

长度: 4.5

宽度: 7.5

面积: 33.75

成本: 2362.5


8:多态

C# 多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。

多态可以是静态的或动态的。在静态多态中,函数的响应是在编译时发生的。在动态多态中,函数的响应是在运行时发生的。

在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。

多态就是同一个接口,使用不同的实例而执行不同操作

现实中,比如我们按下 F1 键这个动作:

如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
    如果当前在 Word 下弹出的就是 Word 帮助;
    在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。

静态多态

您可以在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。不能重载只有返回类型不同的函数声明。

下面的代码演示了几个相同的函数 Add(),用于对不同个数参数进行相加处理:
 

using System;
namespace PolymorphismApplication{    
public class TestData      {          
public int Add(int a, int b, int c)          {              
return a + b + c;          
}          
public int Add(int a, int b)          {              
return a + b;          
}      
}      
class Program      {          
static void Main(string[] args)          {              
TestData dataClass = new TestData();            
int add1 = dataClass.Add(1, 2);              
int add2 = dataClass.Add(1, 2, 3);             
Console.WriteLine("add1 :" + add1);            
Console.WriteLine("add2 :" + add2);          
}      
}  
}

下面的实例演示了几个相同的函数 print(),用于打印不同的数据类型:

using System;
namespace PolymorphismApplication{   
class Printdata   {      
void print(int i)      {         
Console.WriteLine("输出整型: {0}", i );      
}       
void print(double f)      {         
Console.WriteLine("输出浮点型: {0}" , f);      
}       
void print(string s)      {         
Console.WriteLine("输出字符串: {0}", s);      
}      
static void Main(string[] args)      {         
Printdata p = new Printdata();         // 调用 print 来打印整数         
p.print(1);         // 调用 print 来打印浮点数         
p.print(1.23);         // 调用 print 来打印字符串         
p.print("Hello Runoob");         
Console.ReadKey();      
}   
}
}

当上面的代码被编译和执行时,它会产生下列结果:


输出整型: 1

输出浮点型: 1.23

输出字符串: Hello Runoob

9:封装

C# 封装

封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。

抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。

C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。

一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

public:所有对象都可以访问;
    private:对象本身在对象内部可以访问;
    protected:只有该类对象及其子类对象可以访问
    internal:同一个程序集的对象可以访问;
    protected internal:访问限于当前程序集或派生自包含类的类型。
Public 访问修饰符

Public 访问修饰符允许一个类将其成员变量和成员函数暴露给其他的函数和对象。任何公有成员可以被外部的类访问。

using System; 
namespace RectangleApplication{    
class Rectangle    {        
//成员变量        
public double length;        
public double width;         
public double GetArea()        {            
return length * width;        
}        
public void Display()        {            
Console.WriteLine("长度: {0}", length);            
Console.WriteLine("宽度: {0}", width);            
Console.WriteLine("面积: {0}", GetArea());        
}    
}
// Rectangle 结束     
class ExecuteRectangle    {        
static void Main(string[] args)        {            
Rectangle r = new Rectangle();            
r.length = 4.5;            
r.width = 3.5;            
r.Display();            
Console.ReadLine();        
}    
}
}

当上面的代码被编译和执行时,它会产生下列结果:

长度: 4.5

宽度: 3.5

面积: 15.75

在上面的实例中,成员变量 length 和 width 被声明为 public,所以它们可以被函数 Main() 使用 Rectangle 类的实例 r 访问。

成员函数 Display() 和 GetArea() 可以直接访问这些变量。

成员函数 Display() 也被声明为 public,所以它也能被 Main() 使用 Rectangle 类的实例 r 访问。

Private 访问修饰符

Private 访问修饰符允许一个类将其成员变量和成员函数对其他的函数和对象进行隐藏。只有同一个类中的函数可以访问它的私有成员。即使是类的实例也不能访问它的私有成员。

下面的代码说明了这点:
 

using System; 
namespace RectangleApplication{    
class Rectangle    {        
//成员变量        
private double length;        
private double width;         
public void Acceptdetails()        {            
Console.WriteLine("请输入长度:");            
length = Convert.ToDouble(Console.ReadLine());            
Console.WriteLine("请输入宽度:");            
width = Convert.ToDouble(Console.ReadLine());        
}        
public double GetArea()        {            
return length * width;        
}        
public void Display()        {            
Console.WriteLine("长度: {0}", length);            
Console.WriteLine("宽度: {0}", width);            
Console.WriteLine("面积: {0}", GetArea());        
}    
}
//end class Rectangle        
class ExecuteRectangle    {        
static void Main(string[] args)        {            
Rectangle r = new Rectangle();            
r.Acceptdetails();            
r.Display();            
Console.ReadLine();        
}    
}
}

当上面的代码被编译和执行时,它会产生下列结果:

 

请输入长度:

4.4
请输入宽度:

3.3

长度: 4.4

宽度: 3.3

面积: 14.52


在上面的实例中,成员变量 length 和 width 被声明为 private,所以它们不能被函数 Main() 访问。

成员函数 AcceptDetails() 和 Display() 可以访问这些变量。

由于成员函数 AcceptDetails() 和 Display() 被声明为 public,所以它们可以被 Main() 使用 Rectangle 类的实例 r 访问。

Protected 访问修饰符

Protected 访问修饰符允许子类访问它的基类的成员变量和成员函数。这样有助于实现继承。

Internal 访问修饰符

Internal 访问说明符允许一个类将其成员变量和成员函数暴露给当前程序中的其他函数和对象。换句话说,带有 internal 访问修饰符的任何成员可以被定义在该成员所定义的应用程序内的任何类或方法访问。

10:xml

什么是XML?

XML 指可扩展标记语言(EXtensible Markup Language)。
XML 是一种很像HTML的标记语言。
XML 的设计宗旨是传输数据,而不是显示数据。
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准。

XML的头部声明和注释怎么写?

声明


XML规定每一个正规的XML文档都应当由一个XML声明开始,不允许在前面再有其他字符,甚至空格或者注释。也就是说,XML声明必须是XML文档的第一个内容。

XML声明的一般语法格式为:
 

<?xml version="1.0" encoding="gb2312" standalone="yes"?>

这些属性已经在XML 1.0规范中做出了定义:


(1) 像所有的处理指令一样,XML声明也是由“<?”开始,以“?>”结束。

(2) “<?”之后的“xml”表示该文件 是一个XML文件。
(3) version——不能省略,其值必须为“1.0”。该属性用来保证对XML未来版本的支持。
(4) encoding——可选,其值必须是一种合法的字符编码,例如“UTF-8”、“UTF-16”或“ISO-8859-1”(即Latin-1字符编码)。所有XML解析器都要求至少支持“UTF-8”或“UTF-16”。如果没有包含这个属性,就假设是“UTF- 8”或“UTF-16”编码,这取决于开始的“<?xml”字符串的格式。采用哪种编码取决于文档中用到的字符集。

下面是几个常见的编码:


简体中文码:GB2312。
繁体中文码:BIG5。
压缩的Unicode编码:UTF-8。
压缩的UCS编码:UTF-16。
(5)standalone——可选,其值必须是“yes”或“no”。如果是“yes”,就意味着所有必需的实体声明都包含在文档中;如果是“no”,就意味着需要外部的DTD。

注释


在XML文档中适当地添加一些有意义的注释文字,可以大大增进文档的可读性。XML处理器通常会忽略文档中的这些注释语句,不对其作出任何处理。

XML文档中的注释语句格式如下:
 

 <!--注释文字-->

注意:


1、注释可以输入除了“–”之外的文字。

2、注释可以放在除元素标记之内的任何地方。

3、注释语句放在文档的元素内容之中是可以的。

4、可以对标记进行注释。

5、注释不能嵌套使用。

处理指令


处理指令(Processing Instruction,PI)是XML 文档中为XML 处理程序提供必要的处理信息的指令描述。XML 解析器会把它原封不动地传递给XML 应用程序,由应用程序来根据该指令进行必要处理,或者再把它原封不动地传递给下一个应用程序。
如例 XML声明之后的 <?xml-stylesheet type=“text/xsl” href=“1-4.xsl”?>。
处理指令一般具有下列语法格式:
<?处理指令名称 处理指令信息?>


说明:


1)处理指令必须以“<?”开始,以“?>”结束。
2)“处理指令名称” 可以是应用程序的实际名称,也可以是其它能被应用程序正确识别处理的名称。指令名的大小 写必须注意。
3)“处理指令信息”是指被传送到处理软件或脚本程序的信息,可由除了“?>”之外的任何连续字符组成。

XML 文档实例

<?xml version="1.0" encoding="UTF-8"?>
<note>  
<to>Tove</to>  
<from>Jani</from>  
<heading>Reminder</heading>  
<body>Don't forget me this weekend!</body>
</note>

11:文件流

C# 文件的输入与输出

一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。

从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)。

C# I/O 类

System.IO 命名空间有各种不同的类,用于执行各种文件操作,如创建和删除文件、读取或写入文件,关闭文件等。

下表列出了一些 System.IO 命名空间中常用的非抽象类:

         I/O 类                                                                    描述
        BinaryReader                                从二进制流读取原始数据。
        BinaryWriter                                  以二进制格式写入原始数据。
        BufferedStream                             字节流的临时存储。
        Directory                                        有助于操作目录结构。
        DirectoryInfo                                 用于对目录执行操作。
        DriveInfo                                        提供驱动器的信息。
        File                                                  有助于处理文件。
        FileInfo                                           用于对文件执行操作。
        FileStream                                      用于文件中任何位置的读写。
        MemoryStream                              用于随机访问存储在内存中的数据流。
        Path                                                对路径信息执行操作。
        StreamReader                               用于从字节流中读取字符。
        StreamWriter                                 用于向一个流中写入字符。
        StringReader                                 用于读取字符串缓冲区。
        StringWriter                                   用于写入字符串缓冲区。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值