Java学习第五周总结

一 . 多态

1 . 概念 :

一个事物体现的不同形态

2 . 多态的前提条件

(1)必须存在继承关系,如果没有继承关系就没有多态

(2)必须存在方法重写,需要将父类的功能覆盖掉,让子类完成自己的功能.    (强制重写)

(3)需要存在"父亲引用指向子类对象"

格式

父类名 对象名 = new 子类名();   --------->(向上转型)用的是父类的东西

3 . 多态中的成员访问特点

(1)成员变量

编译看左,运行看左.------如果编译通过了,说明父类中存在变量,运行看左,使用父类的东西

(2)成员方法---非静态的

编译看左,运行看右------因为子类出现了父类一模一样的方法,覆盖父类的方法

(3)静态的成员方法

和类相关,被称为---类成员,随着类的加载而加载,访问通过类名访问

(4)构造方法

因为存在继承关系,存在无参构造/有参构造,都需要父类先初始化,然后才是子类,分层初始化

4 . 多态的好处

(1)可以提高代码的复用性<继承保证的>

(2)可以提高代码的扩展性<多态保证---父类引用指向子类对象>

5 . 多态的弊端

向上转型-------使用的是父类的东西,不能访问子类的特有功能

解决方法:  

(1)直接创建具体的子类,需要在堆内存中继续开辟空间,消耗内存空间

(2)向下转型-----将父类的引用强转子类引用,节省内存

二 . abstract 关键字 (抽象)

1.抽象的概念 :

在现实中,将比较概括性的食物称为--------抽象的事物

2.书写格式

abstract  class  类名 { }

3.抽象类特点

不能创建对象 不能实例化

4.注意事项:

(1)如果一个类中存在抽象方法,那么这个类一定是抽象类

(2)一个抽象类中,不一定都是抽象方法

    抽象方法只有方法声明,没有方法体现

    权限修饰符 (除过private / fainl / static ) abstract 返回值类型 方法名(形式参数列表)

(3)抽象类的子类如果为抽象类,会存在具体子类,否则没有意义,抽象类的子类为具体类才能创建对象

(4)抽象类的本质:强制子类必须完成的事情

5.抽象类的成员特点

(1)成员变量:既可以是变量,也可以是常量

(2)成员方法:既可以是抽象方法,也可以是非抽象方法

(3)构造方法:存在有参/无参构造方法,分层初始化

三 . 接口

1.概念:

接口就是描述事物本身之外的额外功能-------扩展功能

2.接口格式

inferface 接口名 { }--------------------使用<大驼峰命名法>

实现关键字 implements

3.接口的特点

(1)不能实例化

(2)接口中成员方法:只能是抽象方法,不能有方法体

4.接口注意事项:

(1)接口的子实现类可能是抽象类,抽象类肯定会存在具体的子类,否则没有意义

(2)具体类是通过接口多态进行实例化

5.接口的成员特点

(1)成员变量:只能是常量,存在默认修饰符public static final 可以省略不写

(2)成员方法:只能是抽象方法,存在默认修饰符 publi abstract

(3)构造方法:接口没有构造方法,因为接口只是为了提供事物的额外功能,谁实现了接口,就具备这个功能

6.接口和抽象类的区别

(1)成员区别

接口:

    成员变量:只能是常量,存在默认修饰符public static final 可以省略不写

    成员方法:只能是抽象方法,存在默认修饰符 publi abstract

    构造方法:接口没有

抽象类

     成员变量:既可以是常量也可以是变量

     成员方法:既可以存在抽象方法,而且抽象方法abstract不能省略,也可以存在非抽象方法;

     构造方法:存在无参/有参,继承关系.先让父类初始化,然后再是子类初始化(分层初始化)

(2)关系区别      

     <1>类与类之间:只支持单继承,不支持多继承,但可以多层继承.

     <2>类与接口:实现关系 implements;一个类继承另一个类的同时,可以实现多个接口

     <3>接口与接口:继承关系 extends,不仅支持单继承,也可以多继承,也可以多层继承

(3)设计理念的区别

     <1>抽象类------存在继承关系extends,体现的是"is  a"关系

     <2>接口-------存在实现关系implements,提供的是额外功能,体现的是"like a"关系

四 . 方法形式参数问题研究

1.为基本数据类型

实际参数需要传递当前具体基本类型的数据值即可

2.为引用数据类型

<1>具体类:调用该方法,实际参数需要传递的是当前具体对象

<2>抽象类:调用该方法,实际参数需要传递的是当前抽象类的子类对象,抽象类多态完成

<3>接口:调用该方法,实际参数需要传递的是当前接口的子实现类对象,接口多态完成

五 . 方法返回值类型的研究

1.方法返回值为基本数据类型

返回具体的结果: return 结果值;

2.方法返回值为引用数据类型

<1>具体类:如果一个方法的返回值是一个具体类,那么该方法的就需要返回当前类具体对象

<2>抽象类:如果一个方法的返回值是一个抽象类型,那么该方法需要返回当前抽象类的子类对象,使用抽象类多态

<3>接口:如果一个方法的返回值是一个接口类型,接口不能实例化,需要返回当前接口的子实现类对象,使用接口多态

六 . instanceof关键字

instanceof: instanceof是java中的运算符,左边是对象,右边是类,当对象是右边类或者子类所创建对象时,返回 true , 否则返回 false .

(1)类的实例包括本身的实例,以及所有直接或间接子类的实例

(2)instanceof 左边显示声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误

if(a instanceof  Cat){
            System.out.println("这是猫实例");
        }else if(a instanceof  Dog){
            System.out.println("这是狗实例");

七 . 权限修饰符的使用范围

                    同包下当前类中    同包下子类/无关类    非同包子类    非同包无关类        
 
 
private                   Y                NO                NO            NO
 
默认(default)              Y                Y                NO            NO
 
protected                 Y                 Y                Y             NO
 
public                    Y                Y                  Y            Y

八 . 带包编译与运行

1.同包下

(1) 对 java 文件进行编译

javac  -  d  .  源文件名称.java      eg:javac -d . Demo.java

(2)带包进行运行

java 包名.类名                             eg:java com.qf.Demo

2.不同包下

(1)导包

import . 包名 . 类名 ;

(2)编译

javac  -d  .  源文件名称.java

(3)运行

java 包名.类名

九 . 内部类

1.概念:

在一个类中定义另一个类

2.内部类分类

1  .  成员内部类:在一个类中的成员位置定义的类

(1)成员内部类的特点

成员内部类(非静态)的成员可以访问外部类的成员,包括私有.

(2)直接访问成员内部类成员:非静态

外部类名.内部类名 对象名 = 外部类对象.内部类对象 ;

Outer.Inner oi = new Outer().new Inner() ;

(3)静态成员内部类

无论静态还是非静态成员方法,访问外部类成员变量,外部类成员变量都必须是静态的;

静态的成员内部类随着外部类的加载而加载;

直接访问静态成员内部类中成员方法:   

外部类名.内部类名 对象名  =  new  外部类名.内部类名;

Outer.Inner oi = new Outer.Inter();

访问静态的成员内部类的静态成员方法:

Outer.Inner.show()

2  .  局部内部类:在一个类的成员方法中定义的类.

<1>局部内部类特点

局部内部类(非静态)的成员可以访问外部类的成员,包括私有.

3  .  匿名内部类

<1>匿名内部类:没有名字的类.

<2>new 接口/类名(){

                重写方法()完成业务功能

};


class Outer{
     public void method(){
    //访问一个
    new Inter(){
 
            @Override
            public void show() {
                System.out.println("show Inter...");
            }
         }.show() ;
 
    //访问两个个成员方法
    public void method(){
     Inter inter = new Inter() {//还是接口多态方式:不过子实现类没类名
 
            @Override
            public void show() {
                System.out.println("show Inter...");
            }
 
            @Override
            public void show2() {
                System.out.println("show2 Integer...");
            }
        };
        inter.show() ;
        inter.show2() ;
    }

3  .  匿名内部类的本质:就是继承了该抽象类或者实现了该接口子类对象;

4  .  使用场景:匿名内部类使用在方法定义中或者是方法声明上:局部位置中使用

可能方法的形式参数是一个接口/抽象类

可能方法返回值类型是一个接口/抽象类

十 . object 类

object类是超类或基类,所有类的直接或间接父类,位于继承树最顶层;任何类没有书写extends显示继

承某个类,都默认继承object类,否则为间接继承.

1. getclass()

getclass():  返回引用中存储的实际对象类型,通常用于判断两个引用中实际存储对象类型是否一致.

public final Class getClass():表示正在运行的类的实例,(当前类的字节码文件对象).


 getClass()目的就是可以获取正在的运行的类(Class):代表的就是字节码文件对象
 Student s1 = new Student() ;
 Class c = s1.getClass();  //c:  Class com.qf.Student;
 
 public String getName():获取当前类的字符串形式:
 c.getNme();   //com.qf.Student  全限定名称
 
 Student s2 = new Student() ;
 Class c1 = s1.getClass() ;  class com.qf.day15_mytest.Dog
 Class c2 = s2.getClass() ;  class com.qf.day15_mytest.Dog
 System.out.println(s1==s2) ;   分别需要开辟空间
 System.out.println(c1==c2) ;   因为类就加载一次,产生的字节码文件就一个

2.hashCode

hashCode方法是返回该对象的十进制哈希码值;把它可以看成是一个"地址值",不是真实意义的地址

值,和哈希表有关,不同的对象,哈希码值不同.

3. toString

返回对象的字符串表示形式(返回对象的成员信息表达式);应该是一个简明扼要的表达,容易让人阅读,建议所有子类覆盖此方法(快捷键:  Alt + ins)。

public class Person{
    private String name;
    private int age;
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person();            重写前:com.qf.day16_test.Person@1b6d3586
        System.out.println(p1);              重写后:Person{name='null', age=0}
         //(p1) = (p1.toString)                    
    }
}

4. equals

public boolean equals(Object obj):表示其他对象与此对象是否"相等".

(1)==和equals的区别

<1>==连接基本数据类型:  比较基本数据类型数据值是否相等

      ==连接引用数据类型:  比较引用数据类型地址值是否相等

<2>equals默认比较地址值是否相同,建议子类重写equals方法,比较成员信息是否相同,重写equals同时还要重写hashCode()方法,保证哈希码值必须一样,才能比较equals.  快捷键:alt+ins
 

public class Person{
    private String name;
    private int age;
     @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        Person person = (Person) o;
 
        if (age != person.age) return false;
        return name.equals(person.name);
    }
 
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}
 
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("张三",23);
        Person p2 = new Person("张三",23);
        System.out.println(p1 == p2);        重写前:false  重写后:false
        System.out.println(p1.equals(p2));   重写前:false  重写后:true
    }
}

5. clone

protected Object clone():  创建并返回此对象的副本(浅克隆);  简单理解:复制对象,获取对象的成员

(1)throws CloneNotSupportedException:调用过程中可能存在克隆不支持的异常;对于jdk提供的类

的方法本身存在异常.谁调用这个方法,必须做出处理,否则报错,最简单的方式继续往上抛 throws.

(2)clone为受保护的方法,无关类中不能访问,需要在当前子类中重写clone方法,需要实现Cloneable

接口,这个接口没有字段,连方法都没有,标记接口,标记这个类是否能够使用克隆.
 


class Persons implements Cloneable{
    private String name;
    private int age;
  
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Persons p1 = new Persons("张三",23);
        System.out.println(p1);
        Object p2 = p1.clone();
        System.out.println(p2);
    }
}

6.Scanner

Scanner:java.util的类:文本扫描器

构造方法:   public Scanner(InputStream source)

成员方法:   <1>判断功能 haxNextXXX():判断下一个录入都是是否是XXX类型

public boolean hasNextInt():

public boolean hasNextLine():

<2>获取功能  nextXXX()

public int nextInt()

public String nextLine()  ......
 


public class ScannerDemo {
    public static void main(String[] args) {
        //public Scanner(InputStream source):形式参数时候一个抽象类,需要有子类对象
        //System类中存在一个"标准输入流"in
        //public static final InputStream in
        InputStream inputStream = System.in ; //字节输入流
        //创建键盘录入对象
        Scanner sc = new Scanner(inputStream) ;
        System.out.println("录入一个数据:");
       /* int num = sc.nextInt(); //获取功能
        System.out.println(num);*/
        //java.util.InputMismatchException:录入的数据和需要接收的num类型不匹配
        //Scanner类的提供的判断功能
        if(sc.hasNextInt()){
            //录入的int类型
            //接收int
            int num = sc.nextInt() ;
            System.out.println("您输入的数据是:"+num);
        }else if(sc.hasNextLine()){
            //录入的String
            String line = sc.nextLine() ;
            System.out.println("您输入的数据是:"+line);
        }else{
            System.out.println("对不起,没有提供其他接收的类型值...");
        }
 
    }
}

十一 . String

抽取方法快捷键:  ctrl + alt + m;

1.概念

String类代表字符串,Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例,"字符串本身就是常量".

2.String的特点

字符串不变的; 它们的值在创建后不能被更改.

推荐访问方式:  String 变量名   =  "字符串常量" ;

字符串是常量:在内存中:方法区中的常量池中存储

3.面试题
String s = "hello" ;和String s2 = new String("hello") ;两个有什么区别,分别创建了几个对象?

答:共同点:都是在创建一个字符串对象"hello";

不同点:内存执行不一样;前者只是在常量池中开辟空间,创建一个对象;后者在堆中开辟空间,而且常量池里面存在常量----常量池中标记 ,创建两个对象

4.String里的常用构造方法

<1>public String():无参构造

<2>String(byte[] bytes):将字节数组可以构造字符串对象

<3>public String(byte[] bytes,int offset,int length):将一部分字节数组构造成字符串对象

<4>public String(char[] value):将字符数组构造成字符串对象

<5>public String(char[] value, int offset,int count):将一部分字符数组构造成字符串对象

<6>public String(String original):创建一个字符串对象,里面存储字符串常量
5.String类获取功能

<1>char charAt(int index)  :获取指定索引处的字符值

<2>public String concat(String str):拼接功能:拼接新的字符串

<3>public int indexOf(int ch):返回指定字符第一次出现的字符串内的索引

<4>public int indexOf(String str):返回指定字符串第一次出现在字符串内的索引

<5>int lastIndexOf(int ch)  :查询指定字符最后一次出现的索引值

<6>int length()  :获取字符串长度

<7>public String[] split(String regex):字符串的拆分方法:返回字符串数组 (重要)

<8>String substring(int beginIndex) :字符串截取功能(重要),默认从beginIndex开始索引截取到末尾

<9> public String substring(int beginIndex,int endIndex)    :从指定位置开始截取到指定位置结束(包前不包后)
6 String类的转换功能

<1>public char[] toCharArray():将字符串转换字符数组

<2>byte[] getBytes()  :使用平台的默认字符集进行编码过程:将字符串--->字节数组

<3>byte[] getBytes(String charset):使用指定的字符集进行编码  "GBK/UTF-8"

<4>public String toLowerCase():将字符串中的每一个字符转换成小写

<5>public String toUpperCase():将字符串中的每一个字符转换成大写

<6>static String valueOf(boolean b/float/long/double/int/char /....Object)  :万能方法:将任意的数据类型转换成String :静态的功能
7 .String类的判断功能

<1>public boolean contains(String s):判断是否包含子字符串

<2>public boolean startsWith(String prefix):判断是否以指定的字符串开头

<3>public boolean endsWith(String suffix):判断是否以指定的字符串结尾

<4>boolean equals(Object anObject)  :判断字符串内容是否相等:区分大小写

<5>boolean equalsIgnoreCase(String anotherString)  :判断字符串内容是否相等,忽略大小写

<6>public boolean isEmpty():判断字符串是否为空
8 .String类其他功能

<1>public String replace(char oldChar,char newChar):将新的字符值把旧的字符替换掉

<2>public String replace(String oldChar,String newChar):将新的字符串值把旧的字符串替换掉

<3>public String replaceAll(String regex,String replacement):用指定的replacement替换regex字符串内容

<4>public String trim():去除字符串前后两端空格;  一般用在:IO中传输文件(读写文件)
9 String作为形式参数传递的特点

String类型作为形式参数和基本类型作为形式的效果一样,形式参数的改变不会直接影响实际参

数,String类型为特殊的引用类型.


public class StringTest {
    public static void main(String[] args) {
        String s1 = "helloworld" ;
        System.out.println(s1) ;
        change(s1) ;
        System.out.println(s1) ;
        private static void change(String s1) {//String类型作为形式参数
        System.out.println(s1) ;
        s1+="javaEE" ;
        System.out.println(s1) ;
    }
}

十二 .StringBuffer

1.概念
StringBuffer: 简称"字符串缓冲",线程安全的,而且可变的字符序列.

2. StringBuffer面试题

StringBuffer和StringBuilder有什么区别?

答:共同点:两者都是字符串区,支持可变的字符序列,而且都有互相兼容的API(功能相同的);

不同点:<1>前者:线程安全的类,多线程环境下使用居多

            <2>后者:线程不安全的类,单线程程序中使用居多

3. StringBuffer的构造方法

<1>StringBuffer();无参构造方法  :使用居多

<2>StringBuffer(int capacity):指定容量大小的字符串缓冲区

<3>StringBuffer(String str) :指定缓冲区的具体内容str,容量大小=16个默认容量+当前字符串长度

<4>public int length()获取字符缓冲区中的长度

<5>public int capacity():获取字符串缓冲区中的容量大小

4. StringBuffer添加和删除功能

<1>StringBuffer append(任何数据类型):将任何数据类型的数据追加字符序列中(字符串缓冲区)

<2>StringBuffer insert(int offset, String str)  :插入元素:在指定位置插入指定的元素

<3>public StringBuffer deleteCharAt(int index):在指定的位置处删除的指定的字符,返回字符串缓冲区本身

<4>public StringBuffer delete(int start,int end):删除指定的字符从指定位置开始,到end-1处结束

5. StringBuffer反转功能

public StringBuffer reverse():反转功能.

public String toString():返回表示此数据中的数据的字符串.

6.StringBuffer和String相互转换

(1)Sting转换为StringBuffer

<1>方式1:使用StringBuffer的有参构造方法

String s = "helloJavaEE" ;    StringBuffer(String s);

<2>方式2:使用StringBuffer无参构造方法+append(String s)

StringBuffer sb2 = new StringBuffer() ;

sb2.append(s) ;

(2)将StringBuffer转换为String

<1>String类型构造方法:public String(StringBuffer buffer)

String str = new String(buffer) ;

<2>public String toString()

String str2 = buffer.toString();

7.StringBuffer截取功能

substring(int start):从指定位置截取到默认结束,返回的新的字符串.substring(int start, int end) :从指定位置开始截取,到指定位置结束(包前不包后).

StringBuffer sb = new StringBuffer() ;
String resultStr = sb.substring(5);
String resultStr2 = sb.substring(5, 9);


8.String和StringBuffer有什么区别

String:是常量,一旦被赋值,其值不能被更改;它的不可变的字符序列;作为形式参数,形式参数的改变

不会影响实际参数,特殊的引用类型,和基本数据类型作为形式参数的效果一样.

StringBuffer:字符串缓冲区,里面存储的字符序列;是可变的字符序列,线程安全的类,同步,执行效率

低,单线程程序中使用StringBuilder替代StringBuffer;作为形式参数,形式参数的改变会直接影响实际

参数.

十三 . 包装类


1.概念

基本数据类型所对应的引用数据类型;Object可同一所有数据,包装类的默认值是null.

  1. byte     Byte

  2. short     Short

  3. int     Integer

  4. long     Long

  5. float     Float

  6. double     Double

  7. char    Character

  8. boolean   Boolean

2. 将Int转换为字符串

<1>public static String toBinaryString(int i):将整数转换字符串形式的二进制

<2>public  static String toOctalString(int i)  :将整数转换字符串形式的八进制

<3>public static String toHexString(int i):将整数转换成字符串形式的十六进制

System.out.println(Integer.toBinaryString(100)) ;
System.out.println(Integer.toOctalString(100)) ;
System.out.println(Integer.toHexString(100)) ;

3. 求int类型的取值范围

<1>public static final int MAX_VALUE:  求最大值

<2>public static final int MIN_VALUE:  求最小值

  1. System.out.println(Integer.MIN_VALUE) ;

  2. System.out.println(Integer.MAX_VALUE) ;

  3. 注意:

    jdk5以后:自动拆箱和装箱.  基本数据类型和包装类自动转换.

    装箱:基本数据类型---引用数据类型    拆箱:引用数据类型----基本数据类型

4 Integer的构造方法 

Integer(int value):将int类型构造成Integer对象

Integer(String s) 将String类型构造成Integer对象:  注意:要使用第二个构造方法,前提是必须是数字

字符串,否则会抛出异常:throws NumberFormatException .

int i = 100 ;
Integer ii = new Integer(i) ;
System.out.println(ii);
 
String s = "200" ;
Integer i2 = new Integer(s) ;
System.out.println("i2:"+i2) ;

5.基本功能

<1>public static Integer valueOf(int i):     int----integer

<2>public static Integer valueOf(String s):    String-----Integer

<3>public int intValue():       Integer-----Int  转换为六种基本类型

<4>public String toString():   返回String表示此对象Integer的价值   Integer------String

<5>public static String toString(int i);   int -----String

<6>parseInt(String s):    将字符串解析为带符号的十进制整数  String-----int

6 .典型例题:看程序,写结果

注意:看当前传进来的整数值是否在内存缓冲区-128-127之间;如果在直接取值,如果不在,就会创建

新的Integer对象.


public class IntegerTest {
    public static void main(String[] args) {
        Integer i1 = new Integer(127) ;
        Integer i2 = new Integer(127) ;
        System.out.println(i1==i2) ;//false
        System.out.println(i1.equals(i2)) ;//true
 
        Integer i3 = new Integer(127) ;
        Integer i4 = 127 ;
        System.out.println(i3==i4) ;//false
        System.out.println(i3.equals(i4)) ;//true
 
        Integer i7 = new Integer(128) ;
        Integer i8 = 128 ;  //超了范围-128 ~127  new Ineteger(128) ;
        System.out.println(i7==i8) ;//false
        System.out.println(i7.equals(i8));//true
 
        Integer i5 = new Integer(128) ;
        Integer i6 = new Integer(128) ;
        System.out.println(i5==i6) ; //false
        System.out.println(i5.equals(i6));//true
 
        Integer i9 = 128 ;  //-128-127
        Integer i10 = 128 ;
        System.out.println(i9==i10) ; //false
        System.out.println(i9.equals(i10));//true
 
        Integer k1 = 100;
        Integer k2 = 100;
        System.out.println(k1 == k2);//true
        System.out.println(k1.equals(k2));//true
 
    }
}

7.String----与int相互转换

(1)int-----String

<1>方式1:空串拼接

int i = 100 ;
String result = ""+i ;
System.out.println("result:"+result);//"100"

<2>利用Integer中间桥梁

int i = 100 ;
Integer ii = new Integer(i) ;
String result2 = ii.toString();

<3>利用Integer静态方法:  public static String toHexString(int i):返回16进制无符号整数值的字符串

int i  = 100;
String result3 = Integer.toHexString(i);

(2)String-----int

<1>Integer构造方法+intValue()

String s = "50" ;
Integer i1 = new Integer(s) ;
int intResult = i1.intValue();

<2>Integer静态功能直接转换:  public static int parseInt(String s)

String s = "50" ;
int intResult2 = Integer.parseInt(s) ;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值