基于C#的GIS开发20210422之C#知识点总结、数组、数据类型、字符串总结、函数重载、字段与属性的区分、构造函数的应用、属性设置、普通类与抽象类、面向对象关系梳理

在20210419的基础上进行改进,和学习。

①C#小知识点总结

一、C#中的数组定义

0)数组声明

①C#声明数组时,方括号[]必须跟在类型后面,而不是标识符后面。
②C#声明数组时支持分配内存的方括号内是整型变量或变量表达式,只要事先确定了变量的值即可

int[] mySigArray = new int[n];    

n的值必须事先确定,声明之后即使改变n的值数组大小也不会变

例子:

//           int[] ii;
//声明数组,此处仅仅声明
 //创建数组,数组赋值方式有两种
//方法一
            //ii = new int[4];
            //ii[1] = 1;
            //ii[2] = 2;
            //ii[4] = 4;//其实是越界了,所以是错的
//方法二
            int[]ii={1,2,3,4};//创建同时,进行赋值操作

1)一维数组:

不定长:

int[] ii= new int[]{1,2,3,4,5,6};

定长:

int[] ii= new int[3]{1,2,3};

区别在于是否在[]中填入数字

2)二维数组

不定长:

int[,] ii= new int[,]{{1,2,3},{1,2,3}}; 

定长:

int[,] ii= new int[2,2]{{1,2},{1,2}};

多维以此类推

区分:
声明锯齿数组(数组的数组)

int[][] mySawArray = new int[3][];      //注意与二维数组不同,这里有两个方括号

在这里插入图片描述

3)数组初始化

int[] a = {1,2,3,4};                  //一维数组初始化
int[,] aa= {{1,2,3},{4,5,6},{7,8,9}};     //二维数组初始化
int[][] aaa= {new int[] {1,2},new int[] {3,4,5,6,7,8},new int[] {9,10,11}};   //锯齿数组初始化

4)数组的访问

① 访问上述初始化数组的单个的元素

int i = a[2];        //i=3
int j = aa[2,1];     //j=8
int k = aaa[2][1];     //k=10  注意二维数组与锯齿数组的区别

②遍历访问数组元素
1)C#提供了foreach语句,该语句提供了一种简单、明了的方法来循环访问数组

foreach(int m in myArray)      //将所有数组元素的值加1,myArray可以是一维、多维或锯齿数组
{
    m++;
}   
C# 中 foreach 遍历的用法

1)foreach循环用于列举出集合中所有的元素,foreach语句中的表达式由关键字in隔开的两个项组成。in右边的项是集合名,in左边的项是变量名,用来存放该集合中的每个元素。

https://blog.csdn.net/beauty_1991/article/details/45197931

2)用for循环遍历数组,使用这种方式可以更好的控制数组元素(知道每次循环中的数组对象是哪个),下面这段代码用foreach语句是无法实现的

//for遍历规则数组
nt[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定义一个2行2列2纵深的3维数组a

            for (int i = 0; i < a.GetLength (0) ;i++ )   //用Array.GetLength(n)得到数组[0,1,,,n]上的维数的元素数,0代表行,1列,n代表此数组是n+1维

            {
                for (int j = 0; j < a.GetLength(1); j++)

                {
                    for (int z = 0; z < a.GetLength(2);z++ )//2代表得到纵深上的元素数,如果数组有n维就得写n个for循环

                    {
                        Console.WriteLine(a[i,j,z]);

                    }

                }

            }

for (int i = 0; i< mySawArray.Length; i++)
{
    for (int j = 0; j < mySawArray[i].Length; j++)
    {
            myMulArray[i,j]=mySawArray[i][j];    //把锯齿数组的每个元素赋值给二维数组中相应的元素
    }
}

用foreach循环一次性遍历a数组

 int[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定义一个2行2列2纵深的3维数组a
                      foreach(int i in a)
                      {
                          Console .WriteLine (i);
                      }

3)借助foreach,只能一一取得数组中的元素,并不能利用这种语句改变数组所存储的元素。
4)foreach优点
①C#中使用数组的时候就难免疑问到底使用0开始还是用1开始呢,那么使用foreach就可以避免这类问题。
②对于多维数组操作用foreach就非常简便了

        int[,] nVisited = new int[8,8];
        // Use "for" to loop two-dimension array
        for( int i = 0; i < nVisited.GetLength(0); i++ )
            for( int j = 0; j < nVisited.GetLength( 1 ); j++ )
                Debug.WriteLine( nVisited[i,j].ToString() );
 
        // Use "foreach" to loop two-dimension array
        foreach( int i in nVisited )
            Debug.WriteLine( i.ToString() );

对于三维或更多维,foreach语句不用发生任何变化
③foreach完成类型转换操作,这种体现可能通过如上的例子看不出任何效果,但是对于ArrayList之类的数据集来说,这种操作就显得比较突出

        // Init an arraylist object
        int[] nArray = new int[100];
        ArrayList arrInt = new ArrayList();
        arrInt.AddRange( nArray );
 
        // Use "foreach" to loop an arraylist
        foreach( int i in arrInt )
            Debug.WriteLine( i.ToString() );
 
        // Use "for" to loop an arraylist
        for( int i = 0; i < arrInt.Count; i++ )
        {
            int n = ( int ) arrInt[i];
            Debug.WriteLine( n.ToString() );
        }

5)缺点:
①不能修改枚举成员

②对集合进行删除操作

6)引用文献:

https://www.cnblogs.com/eniac12/p/4393978.html
https://blog.csdn.net/weixin_30361641/article/details/99807441
https://blog.csdn.net/weixin_33720956/article/details/90184585

二、C#中的数据类型

https://blog.csdn.net/sinat_39291423/article/details/77885749

C#的数据类型可以分为3类:数值类型,引用类型,指针类型。

1)数值类型

①整型(9种):

sbyte,byte,short,ushort,int,uint,long,ulong和char。

Sbyte: 代表有符号的8位整数,数值范围从-128 ~ 127
Byte: 代表无符号的8位整数,数值范围从0~255
Short: 代表有符号的16位整数,范围从-32768 ~ 32767
ushort: 代表有符号的16位整数,范围从-32768 ~ 32767
Int: 代表有符号的32位整数,范围从-2147483648 ~ 2147483648
uint: 代表无符号的32位整数,范围从0 ~ 4294967295
Long: 代表有符号的64位整数,范围从-9223372036854775808 ~ 9223372036854775808
Ulong: 代表无符号的64位整数,范围从0 ~ 18446744073709551615。
Char: 代表无符号的16位整数,数值范围从0~65535。

Char类型的可能值对应于统一字符编码标准(Unicode)的字符集。
Char类型与其他整数类型相比有以下两点不同之处:
a,没有其他类型到char类型的隐式转换。即使是对于sbyte,byte和ushort这样能完全使用char类型代表其值的类型, sbyte,byte和ushort到char的隐式转换也不存在。
b,char类型的常量必须被写为字符形式,如果用整数形式,则必须带有类型转换前缀。比如(char)10赋值形式有三种:
char chsomechar=“A”;
char chsomechar=“\x0065”; 十六进制
char chsomechar="\u0065 ; unicode表示法
字符型中有下列转义符:
1,'用来表示单引号
2,"用来表示双引号
3,\ 用来表示反斜杠
4, \0 表示空字符
5, \a 用来表示感叹号
6, \b 用来表示退格
7, \f 用来表示换页
8, \n 用来表示换行
9, \r 用来表示回车
10, \t 用来表示水平tab
11, \v 用来表示垂直tab

②浮点型

1.float
精确到小数点后面7位。

2.double
精确到小数点后面15位或16位。

备注:
如果二元操作中的其中一个操作数为浮点类型,那么另外一个操作数是整型或浮点类型,运算规则如下:
a,如果其中一个操作数是整型,则操作数被转换为另一个操作数的浮点数类型;
b,如果操作数之一为double,则另一操作数也被转换成double类型,运算以double类型的精度和取值范围进行,并且所得结果也为double类型;
c,否则,运算至少将以float类型的取值范围和精度进行,并且所得结果也为float型。

decimai类型(小数类型)

小数类型非常适用于金融和货币运算。数值范围从1.010 -28~7.9 10 28,精确到小数点后面28位。

布尔型:值为true或false。
没有标准能实现布尔类型和其他类型的转换。

 bool result = 5 > 3 ? true : false;
枚举类型

**枚举类型的元素使用的类型只能是long,int,short,byte。**默认类型是int。默认第一个元素的值是0,每一个连续的元素按1递增。可以给元素直接赋值。如:

enum monthnames 
{
January=1,
February, 
march=31
};
可以强制定义其他类型,如:
enum monthnames : byte
{January ,
February,
March
};
 public enum Gender
    {
        male,
        female
        //注意没有分号
    }

**注意:
1)当我们在类中,使用枚举类型的时候,需要在类外and命名空间内声明枚举类型。
2)枚举类型的声明写法,需不需要“ ;”,哪里用到的是“ , ”
**
例如:

namespace _20210419
{
    //枚举类型,性别判定,要在类外声明
    //enmu-----枚举
    public enum Gender
    {
        male,
        female
        //注意没有分号
    }
    public abstract class Bird 
    {
    }
}
结构类型

结构类型也是一种值类型,使用它的目的是用于创建小型的对象,用以节省内存。

using System;
Struct IP //声明结构
{ 
public byte b1,b2,b3,b4;
}
 
Class test
{
  public static void Main()
  {
    IP myIP;
    myIP.b1=192;
    myIP.b2=168;
    myIP.b3=1;
    myIP.b4=101;
    Console.Write("{0}.{1}。", myIP.b1, myIP.b2);
    Console.Write("{0}.{1}", myIP.b3, myIP.b4);
}
}

2)引用类型

引用类型包括类类型,接口类型,代表类型和数组类型。

1.类

类 类型定义了一种数据结构,这个数据结构中包含了数据成员(如常量,字段和事件等),函数成员(如方法,属性,索引,操作,构造函数和析构函数等)和嵌套 类型。支持继承。

2.对象在这里插入图片描述

对象类型是其他所有类型最终的基础类型。在C#中每一种类型都直接或者间接的源于object这个类类型。

3.字符串

字符串类型是直接从object中继承而来的密封类。String类型的值可以写成字符串文字的形式。

4.接口

见文章20210419

5.代表

代表引用一种静态的方法或者对象实例,引用该对象的实例方法。与其接近的是c/c++中的指针,但指针只能访问静态的函数,代表既能访问静态的方法,也能访问实例的方法。

6.数组

数组是包含一串变量的数据结构。

3)指针类型

当用unsafe修饰符标记时,C#允许在代码块的函数中使用指针变量。不安全代码或非托管代码是使用指针变量的代码块。

基本用法与C++类似

https://www.cnblogs.com/binlyzhuo/articles/1209097.html
https://www.nhooo.com/note/qa07zs.html

三、关于字符串总结学习

字符串一旦声明不再改变。所以只能通过索引来读取指定位置的char,不能对指定位置的char进行修改。

如果要对char进行修改,那么就必须创建一个新的字符串。

字符串的连接+;两边只要有一个是字符串类型,另一个也会被自动转换成字符串类型

两个字符串比较不区分大小写

https://blog.csdn.net/b4834988/article/details/101873040?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161925360816780265470528%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161925360816780265470528&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-3-101873040.pc_search_result_hbase_insert&utm_term=c%23%E4%B8%AD%E5%AD%97%E7%AC%A6%E4%B8%B2
https://www.cnblogs.com/net-sky/p/9235913.html
https://www.cnblogs.com/zysbk/archive/2012/07/30/2615839.html
https://jingyan.baidu.com/article/db55b6094c633c4ba30a2f23.html在这里插入图片描述

1.Replace(替换字符)
2.Remove(删除字符)
3.Substring(字符串提取)
4.Trim(清空空格)
5.ToLower(转换大小写)
6.IndexOf(获取指定的字符串的开始索引)
7.Equals(是否相等)
8.Split(拆分)
9.Contains(判断是否存在)
10.EndsWith,StartsWith(判断字符串的开始或结束)
11.Insert(字符串插入)

string str = "123@163.com";

int index = str.IndexOf('@'); // 返回3  从左向右第一个@

int index = str.LastIndexOf('3'); // 返回6  从右向左第一个3

string newStr = str.SubString(4); //从第4个字符开始截取 返回@163.com

==和Equals区别
==判断引用的地址,Equals判断值,c#会把所有值相同的字符串指向同一个地址,两者的结果没有区别

string[] strs = {"1","2","3"};

string newStr = string.Join("-",strs); //返回 1-2-3

string[] newStrs = newStr.Split('-'); //返回数组{"1","2","3"};

四、C#中的函数重载问题

函数重载

重载的定义:函数名相同,函数的参数列表不同(包括参数个数和参数类型),至于返回类型可同可不同。
重载是可使函数、运算符等处理不同类型数据或接受不同个数的参数的一种方法

https://blog.csdn.net/whc888666/article/details/83933217
1.方法重载:是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数

具体规范:
(1)函数名一定要相同。

(2)函数的参数表必须不同,包括参数的类型或个数
以此区分不同的方法体。
a.如果参数个数不同,就不管它的参数类型了。
b.如果参数个数相同,那么参数的类型必须不同。

(3)方法的返回类型、修饰符可以相同,也可不同。

         public static int AddNumber(int num1,int num2)
        {
            return num1 + num2;
 
        }
       
         public static double AddNumber(int num1, int num2,int num3)
        {
            return num1 + num2;
        }
       
         public static double AddNumber(double num1, int num2)
        {
            return num1 + num2;
        }

构造函数重载:

https://blog.csdn.net/qq_42672770/article/details/105436014

方法名和类名一样,没有返回值
(1)构造函数可以有参数,new对象的时候传递参数即可
(2)如果不指定构造函数,则类有一个默认的无参数构造函数
(3)如果指定了构造函数,则不再有默认的无参数构造函数
(4)如果需要五参数的构造函数,则需要自己来写

例子一:

class Chinese : Person
{
         public Chinese (string name ,int age ,char sex) : base (name,age,sex )        //构造函数的继承调用
         { }
}

五、字段和属性的区分

字段:
存放数据
属性:
get
set

六、C#中构造函数的使用

构造函数的继承调用

例子二:

 public Bird()//构造函数没有返回值
        {
            this.LegNumber = 2;//this是指创建出来的对象本身,
            this._legs = new Leg[2];//创建两个对象数组,每一个成员是leg
            this._legs[0] = new Leg();
            this._legs[1] = new Leg();
            this.chhibangnumber = 2;
            this.Chibang1 = new Chibang[2];
            this.Chibang1[0] = new Chibang();
            this.Chibang1[1] = new Chibang();
            this.BirdGender = Gender.female;
            
            //C#中数组的定义
            //C#中的数据类型
            //int i = 1;
            //double d = 1.213;
            //float f = (float)3.14;
            //decimal dd =(decimal) 11.11;
            //bool b =true;
            //float ff= (float)111.111;
            //string name = "this";
            //string name2 = name.Trim();//把字符串中的空格全部trim掉
            //int ii = name.Substring(1);//取字符串中的字符
            把关于字符串,关于数据类型,总结学习,全部找到
            char c = 'A';
           // int[] ii;//声明数组,此处仅仅声明
                     //创建数组,数组赋值方式有两种
                     //方法一
            //ii = new int[4];
            //ii[1] = 1;
            //ii[2] = 2;
            //ii[4] = 4;//其实是越界了,所以是错的
            //方法二
            int[]ii={1,2,3,4};//创建同时,进行赋值操作
        }
        public Bird(Gender gender):base()//函数的重载,base()在创建的时候先运行无参的构造函数
        {
            this.BirdGender = gender;
        }
        public Bird(int a) : base()//函数的重载,base()在创建的时候先运行无参的构造函数
        {
            //this.BirdGender = gender;
            this.featherNumber = a;
            this.Feathers = new Feather[featherNumber];
            for (int i = 0; i < featherNumber; i++)
            {
                this.Feathers[i] = new Feather();
            }

七、C#属性设置

只读,只写,读写,看逻辑关系,去判断

八、C#普通类和抽象类之间的关系

https://blog.csdn.net/qq_43477676/article/details/112125985
类和对象的关系:

类是一个抽象的概念,是具有相同属性和行为的一组对象的集合,用于创建对象;对象是类的具体实现,是客观真实存在的事物。

抽象类和普通类的区别:

抽象类是概念的抽象,而普通类是事物的抽象(成了概念),那么抽象类就不可以有实例了。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

九、C#中面向对象的各种关系的描述

在这里插入图片描述
1)继承关系:

在C#中,基类就是被继承的类,也可以理解为父类,一个父类可以有多个子类。
C#中一个字类,只能有一个父类

2)组合关系

它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。

3)关联关系
关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类

②程序改进

一、增加“leg”类

1)首先创建leg类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20210419
{
   public  class Leg
    {
        public void Run()
        {
               Console.WriteLine("Hello World!Please put in the first number.");
        }
    }
}

2)其次,明白腿和鸟的关系,腿是一个普通类,不需要继承关系

3)在类中,写入,腿的数量,写入属性函数,可以设置为只读,因为大多鸟类都是只有两个腿的,不需要写入。

虽然,利用快捷方式建立的属性函数,包含读写,但是因为逻辑关系,我们有时候还是会进行舍取

 private int legNumber;
 public int LegNumber
     {
            get => legNumber;
            //set => legNumber = value;
     }

4)调用。
①在构造函数声明

    private Leg[] _legs;

②在构造函数中构造

 public Bird()//构造函数没有返回值
        {
            this.LegNumber = 2;//this是指创建出来的对象本身,
            this._legs = new Leg[2];//创建两个对象数组,每一个成员是leg
            this._legs[0] = new Leg();
            this._legs[1] = new Leg();
            
         }

5)在program主程序中,运用

yanzi yanzii = (yanzi)eat;
 yanzii._Legs[0].Run();

6)以下两行,逻辑错

			//Leg leg = new Leg();
            //leg.Run();

leg是普通类,但是另一个是组件类,腿不能无中生有独立存在,需要依附再鸟的对象上

二、使用接口实现“leg”跑的功能

接口需要基础才能实现内部函数的功能
固写代码为:
①在IRunable接口里写入:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
namespace _20210419
{
   public interface IRunable
    {
        public int RunningSpeed { get; set; }
        public void Runable();

    }
}

②在yanzi类加入

 public class yanzi:Bird,IRunable//继承
 public int RunningSpeed { get; set; }
 public void Runable() {
            Console.WriteLine("I can use IRunable.");

在这里插入图片描述
③在program主函数中进行调用。

    yanzi yanzii = (yanzi)eat;
    yanzii._Legs[0].Run();
    yanzii.Chibang1[0].fly();
    yanzii.Feathers[0].KeepWorm();
    yanzii.Runable();

三、增加“chibang”(翅膀)类

与“leg”写法相一致

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20210419
{
    public class Chibang
    {

        public void fly()
        {

            Console.WriteLine("Hello chibang.");
        }
    }
}

四、增加“next”类(巢穴)

创建巢穴类,与鸟的关系是关联,可以独立存在,即可以new出来
代码如下:
①在“Nest”类中写入:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
//--------------------创建巢穴类,与鸟的关系是关联,可以独立存在,即可以new出来-----------------
namespace _20210419
{
    public class Nest
    {
        public void Live()
        {
            Console.WriteLine("Live");
        }


    }
}

②在Bird类中加入

   private Nest _nest;
   internal Nest BridNest { get => _nest; set => _nest = value; }//为什么写为BridNest,因为要防止命名1的重复
   public Nest BuildNest()
        {
            this.BridNest = new Nest();
            return this.BridNest;
        }

③在program中加入:

           //---------------------------------巢穴--------感受关联关系-----------------
            Nest nest = new Nest();
            // nest.Live();
            //谁去住呢?谁和巢穴关联呢?Bird类要有一个属性去接受巢穴
            yanzii.BridNest = nest;
            yanzii.BridNest.Live();
           

五、使用接口实现“next”的居住功能

步骤如“使用接口实现“leg”跑的功能”

六、增加“egg”类 (蛋)

首先,想要增加,egg类
但是,我们会发现,只有雌鸟会下蛋
所以,我们要设置 性别,
设置函数,判断是否是雌性,即是否有下蛋能力

代码如下:
①egg类中:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;

namespace _20210419
{
   public  class Egg
    {
        public void Buring()
        {
            Console.WriteLine("egg");
        }
    }
}

②性别,可以用int=1,或0.判断,但是不规范。

为了让读取代码更加顺畅,我们设置枚举类,对性别进行设置。

其中,枚举类需要在类外声明,保证在类外也可以对性别进行判断。

并且需要改进构造函数

例如:在Bird中加入:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
namespace _20210419
{
    //枚举类型,性别判定,要在类外声明
    //enmu-----枚举
    public enum Gender
    {
        male,
        female
        //注意没有分号
    }
    public abstract class Bird //首先改为public,加上static类,就不能有构造函数,
    {

	 private Gender _gender;
        public Gender BirdGender { get => _gender; 				set => _gender = value; }
	}
	public Bird(Gender gender):base()//函数的重载,base()在创建的时候先运行无参的构造函数
        {
            this.BirdGender = gender;
        }

        public Egg CreateEgg()
        {
            if (this.BirdGender == Gender.female)
                return new Egg();
            else
                return null;
        }


}

③在program主函数中加入:

            yanzii.CreateEgg();

调用函数。

③封装类库,改进程序

1)创建“类库”项目
2)引入我们项目中的类
3) 修改“类库”项目中,命名空间,改为和类库名一致
4)在菜单栏中,选择,生成解决方案
5)新建项目,控制台应用
6)“添加项目引用”,选择刚才建立的“解决方案”,一个dll文件
7)加入“using 自己类库名”
8)即可使用自己创建的类库

遇到的问题

internal的问题。
首先,我们不难得知,以下三点:

1) internal(内部):限定的是只有在同一程序集中可访问,可以跨类

2) protected(受保护):限定的是只有在继承的子类中可访问,可以跨程序集

3)protected internal:受保护“或”内部修饰符修饰成员,当父类与子类在同一个程序集中,internal成员可见。当父类与子类不在同一个程序集中,子类不能访问父类internal成员,而子类可以访问父类的ptotected internal成员,

即从当前程序集或从包含类派生的类型,可以访问具有访问修饰符 protected internal 的类型或成员。

其次,我们可以简单的理解:
internal,使得我们在编写自己的类库的时候,可以运行成功。
但声称dll文件后,在其他项目中引用就会报错了,这也不难发现,internal是保护在同一程序集中访问,当我们更换程序集就不可访问了。

最后,解决方式:

将internal改为public

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值