【大数据开发必看】Java面向对象

第一章 面向对象基础

1.1 概述

  1. 面向过程与面向对象:

    1. 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节
    2. 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做
    3. 举例:面向过程就是手洗衣服;面向对象就是把衣服丢给洗衣机,这里的对象就是洗衣机。
  2. 面向对象三大特征:封装、继承、多态

  3. 类和对象:

    1. 类是一组属性和行为的集合
    2. 类是对象的模板,对象是类的实例。
  4. 成员变量和成员方法:

    1. 成员变量就是属性,成员方法就是行为
    2. 成员变量是直接定义在类当中的,且在方法外面
    3. 成员方法不要写static关键字(如果写了static关键字,那么该方法就是静态方法,不属于对象,而属于类)
  5. 成员变量和局部变量:

    1. 定义的位置不一样(局部变量在方法的内部,成员变量在方法的外部,直接写在类当中)
    2. 作用范围不一样(局部变量只有方法当中才可以使用,成员变量整个类全都可以通用
    3. 默认值不一样(局部变量没有默认值,成员变量有默认值)
    4. 内存的位置不一样
    5. 生命周期不一样
  6. this关键字:通过谁调用的方法,谁就是this。

  7. 一个标准的类通常拥有四个组成部分:

    1. 所有的成员变量都要使用private关键字修饰
    2. 编写一个无参数的构造方法
    3. 编写一个全参数的构造方法
    4. 为每一个成员变量编写一对get/set方法

这样标准的类也叫做 Java Bean

1.2 三大特性

1.2.1 封装性
  1. 方法就是一种封装
  2. 关键字private也是一种封装(一旦使用private进行修饰,那么本类当中仍然可以随意访问,但是,超出本类范围之外就不能再直接访问了)
1.2.2 构造方法
  1. 定义:专门用来创建对象的方法,当我们通过关键字new来创建对象的时候,其实就是在调用构造方法

  2. 格式:

    public 类名称(参数类型 参数名称){
    	方法体
    }
    
  3. 注意事项:

    1. 构造方法的名称必须和所在的类名称完全一样
    2. 构造方法不要写返回值类型,连void都不写
    3. 构造方法不能使用return
    4. 如果没有编写任何构造方法,编译器会默认赠送一个构造方法
    5. 一旦编写了至少一个构造方法,编译器不再赠送
    6. 构造方法也是可以进行重载
1.2.3 匿名对象
  1. 定义:只有右边的对象,没有左边的名字和赋值运算符。
  2. 格式:new 类名称()
  3. 注意事项:匿名对象只能使用唯一的一次,下次再用不得不再创建一个新对象。
  4. 使用建议:如果确定有一个对象只需要使用唯一的一次,就可以用匿名对象。

使用匿名对象可以进行传参 也可作为返回值

1.2.4 static关键字
  1. 一旦用了static关键字,那么这样的内容不再属于对象自己,而是属于类的,所以凡是本类的对象,都共享同一份。

  2. 如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它;如果有了static关键字,那么不需要创建对象,直接就能通过类名称来使用它。

    例如:静态变量:类名称.静态变量 静态方法:类名称.静态方法()

  3. 注意事项:

    1. 静态不能直接访问非静态(因为在内存中是先有静态内容,后有非静态内容)
    2. 静态方法当中不能用this(因为this代表当前对象,而静态方法与对象无关)
  4. 代码:

    public class MyClass {
        int num; // 成员变量
        static int numStatic; // 静态变量
        // 成员方法
        public void method(){
            System.out.println("这是一个普通的成员方法");
            System.out.println(numStatic); // 成员方法可以访问静态变量
        }
        // 静态方法
        public static void methodStatic(){
            System.out.println("这是一个静态方法");
            System.out.println(numStatic);  // 静态方法可以访问静态变量
    //        System.out.println(num);   // 错误!  静态方法不能直接访问非静态(重点)
    //        System.out.println(this);  // 错误!
        }
    }
    
  5. 静态代码块:

    1. 格式:

      public class 类名称{
          static{
              // 静态代码块的内容
          }
      }
      
    2. 特点:

      1. 当第一次用到本类时,静态代码块执行唯一的一次。
      2. 静态代码块比构造方法先执行。
    3. 典型用途:用来一次性地对静态成员变量进行赋值。

1.2.5 继承性
  1. 继承主要解决的问题就是:共性抽取。

  2. 特点:

    1. 子类可以拥有父类的内容
    2. 子类还可以拥有自己专有的内容
  3. 格式:

    // 定义父类的格式:
    public class 父类名称{    
    }
    // 定义子类的格式
    public class 子类名称 extends 父类名称{
    }
    
  4. 注意事项:

    1. 在父子类继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:

      1. 直接通过子类对象访问成员变量(对象是谁,就优先用谁,没有则往上找)
      2. 间接通过成员方法访问成员变量(该方法属于谁,就优先用谁,没有则往上找)
    2. super关键字:

      1. 在子类中想调用父类的成员变量,使用:super.成员变量名
      2. 在子类中想调用父类的成员方法,使用:super.成员方法名()
      3. 在子类中调用父类构造方法,使用:super()
    3. 方法重写(override)

      1. 在继承关系中,方法的名称一样,参数列表也一样。
      2. 重写的方法前面加上@Override,用来检测重写是否有效
      3. 子类方法的返回值类型小于等于父类方法的返回值类型范围(例如:String<Object)
      4. 子类方法的权限必须 大于等于父类方法的权限修饰符。(public>protected>(default)>private
    4. 父子类构造方法的访问特点:

      1. 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用父类构造后执行子类构造

      2. 可以通过super关键字来调用父类重载构造。

      3. super的父类调用,必须是子类构造方法第一个语句。不能一个子类构造调用多次super构造(易错点

        总结:子类必须调用父类构造方法,不写就会赠送一个super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。

    5. java继承的三大特点:

      1. java语言是单继承的。(一个类的直接父亲只有唯一一个)
      2. java语言可以多级继承
      3. 一个子类的直接父亲是唯一的,但是一个父类可以拥有很多个子类
1.2.6 抽象类
  1. 抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
  2. 抽象类:抽象方法所在的类,必须是抽象类才行,在class之前写上abstract即可。(不是一定有抽象方法)
  3. 如何使用抽象类和抽象方法:
    1. 不能直接创建new抽象类对象。
    2. 必须用一个子类来继承抽象类
    3. 子类必须覆盖重写抽象父类中所有的抽象方法。
    4. 创建子类对象进行使用。
1.2.7 接口
  1. 定义:就是多个类的公共规范。

  2. 格式:

    // 接口是一个引用数据类型,最重要的内容就是其中的:抽象方法
    public interface 接口名称{
        // 接口内容
    }
    /*
    如果是java7,那么接口可以包含的内容有:
    	1.成员变量(其实是常量)
    	2.抽象方法
    如果是java8,还可以额外包括有
    	3.默认方法
    	4.静态方法
    如果是java9,还可以额外包括有
    	5.私有方法
    */
    
  3. 接口中的内容:

    1. 抽象方法:

      1. 定义:

        1. 格式:public abstract 返回值类型 方法名称(参数列表);
        2. 注意事项:
          1. 接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
          2. 这两个关键字修饰符,可以选择性的省略。(不推荐)
          3. 方法的三要素,可以随意定义。
        // 以下四种定义抽象方法的形式都正确
        public abstract void method();
        abstract void method();
        public void method();
        void method();
        
      2. 使用:

        1. 步骤:

          1. 接口不能直接使用,必须有一个“实现类”来“实现”该接口

            格式:public class 实现类名称 implements 接口名{}

          2. 接口的实现类必须覆盖重写(实现)接口中所有的抽象方法

          3. 创建实现类的对象进行使用

      3. 注意事项:如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。

    2. 默认方法

      1. 格式:public default 返回值类型 方法名称(参数列表){ 方法体 }
      2. 备注:接口当中的默认方法,可以解决接口升级的问题
      3. 注意事项:
        1. 接口的默认方法,可以通过接口实现类对象,直接调用
        2. 接口的默认方法,也可以被接口实现类进行覆盖重写
    3. 静态方法

      1. 格式:public static 返回值类型 方法名称(参数名称){ 方法体 }
      2. 使用:
        1. 格式:接口名称.静态方法名(参数)
        2. 注意事项:不能通过接口实现类的对象来调用接口当中的静态方法。
    4. 私有方法

      1. 普通私有方法:
        1. 格式:private 返回值类型 方法名称(参数列表){ 方法体 }
        2. 解决多个默认方法之间重复代码问题
      2. 静态私有方法:
        1. 格式:private static 返回值类型 方法名称(参数列表){ 方法体 }
        2. 解决多个静态方法之间重复代码问题
      3. 注意:private方法只有接口自己才能调用,不能被实现类或别人使用。
    5. 常量:

      1. 格式:public static final 数据类型 常量名称 = 数据值
      2. 注意:
        1. 一旦使用final关键字修饰,说明不可改变
        2. 接口中的常量,可以省略public static final。
        3. 接口中的常量,必须进行赋值,不能不赋值。
        4. 接口中常量的名称,推荐使用完全大写的字母,用下划线进行分隔
  4. 使用接口的时候,需要注意:

    1. 接口是不能有静态代码块和构造方法的。
    2. 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。
    3. 如果实现类所实现的多个接口当中,存在重复的抽象方法,只需要覆盖重写一次即可。
    4. 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
    5. 如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
    6. 一个类如果直接父类当中的方法,和接口当中的默认方法发生了冲突,优先用父类中的方法。
1.2.8 类与接口总结
  1. 类与类之间是单继承的,即直接父类只有一个。
  2. 类与接口之间是多实现的,即一个类可以实现多个接口。
  3. 接口与接口之间是多继承的。
    1. 注意:
      1. 多个父接口当中的抽象方法如果重复,没有关系
      2. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写【必须带default关键字】
  4. 类和接口都可作为成员变量类型。
1.2.9 多态性
  1. extends继承或者implements实现,是多态性的前提。

  2. 定义:一个对象拥有多种形态。

  3. 格式:

    // 代码中体现多态性,其实就是一句话:父类引用指向子类对象
    /* 格式:(左父右子)
    父类名称 对象名 = new 子类名称();
     或者
    接口名称 对象名 = new 实现类名称();
    */
    
  4. 成员变量和成员方法访问特点:和继承一样

    1. 口诀:(左边指的是父类,右边指的是子类)
      1. 成员变量:编译看左边,运行还看左边。
      2. 成员方法:编译看左边,运行看右边
  5. 好处:无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化。

  6. 弊端:不能使用子类或者实现类特有的方法。

  7. 对象的向上转型:(其实就是多态写法)

    1. 格式:父类名称 对象名 = new 子类名称();
    2. 含义:右侧创建一个子类对象,把它当做父类来看待使用
    3. 注意事项:
      1. 向上转型一定是安全的。
      2. 从小范围转向了大范围。
  8. 对象的向下转型:(其实是一个还原的动作)(重点)

    1. 格式:子类名称 对象名 = (子类名称) 父类对象;
    2. 含义:将父类对象,还原成为本来的子类对象。
  9. instanceof关键字:

    1. 格式:父类对象 instanceof 子类名称
    2. 含义:会返回一个boolean值,也就是判断父类引用对象本来是不是该子类
    3. 用处:向下转型的时候一定要利用instanceof进行判断。
1.2.10 final关键字
  1. 代表最终、不可改变的
  2. 用法:
    1. 可以用来修饰一个类
      1. 格式: public final class 类名称{}
      2. 含义:当前这个类不能有任何的子类(太监类)
    2. 可以用来修饰一个方法
      1. 格式:修饰符 final 返回值类型 方法名称(参数列表){}
      2. 含义:这个方法就是最终方法,也就是不能被覆盖重写
      3. 注意:对于类、方法来说,abstract关键字和final关键字不能同时使用。
    3. 可以用来修饰一个局部变量
      1. 格式:final 数据类型 变量名 = 数值;
      2. 含义:这个变量就不能进行更改(一次赋值,终生不变)
      3. 注意:不可变对于基本数据类型来说,数据不可改变;对于引用数据类型来说,地址值不可改变
    4. 可以用来修饰一个成员变量
      1. 格式:修饰符 final 数据类型 变量名 [= 数值];
      2. 注意:
        1. 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了
        2. 对于final的成员变量,那么使用直接赋值,要么通过构造方法赋值
        3. 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
1.2.11 四种权限修饰符
  1. 定义一个类的时候,权限修饰符选择:

    1. 外部类:public/(default)–指什么都不写,而并不是使用关键字default
    2. 成员内部类:都可以
    3. 局部内部类:什么都不能写
    	       public  >  protected  >  (default)  >  private
    同一个类       y              y          y            y
    同一个包       y              y          y            n
    不同包子类     y              y          n            n
    不同包非子类   y              n          n            n
    
1.2.12 内部类
  1. 成员内部类:(在方法外面定义)

    1. 格式:修饰符 class 外部类名称{

      ​ 修饰符 class 内部类名称{

      ​ // …

      ​ }

      ​ // …

      }

    2. 使用:

      1. 间接方式:在外部类的方法当中,使用内部类,然后main只是调用外部类的方法
      2. 直接方式:记住这个公式:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()
    3. 注意:

      1. 内用外,随意访问;外用内,需要内部类对象
      2. 如果出现了成员变量名同名现象,访问外部类成员变量的方式:外部类名称.this.成员变量名
  2. 局部内部类:(在方法里面定义)

    1. 格式:修饰符 class 外部类名称{

      ​ 修饰符 返回值类型 外部类方法名称(参数列表){

      ​ class 局部类名称{

      ​ // …

      ​ }

      ​ }

      }

    2. 注意:

      1. 只有当前所属的方法才能使用它,出了这个方法就不能用了。
      2. 这个内部类的修饰符什么都不能写。
      3. 如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。(也就是只能赋值一次,不能再进行修改,等同于加上了final关键字)
  3. 匿名内部类(属于局部内部类):

    1. 为什么会出现匿名内部类?

      答:使用多态来创建对象的时候,如果接口的实现类(或者是父类的子类)只需要使用唯一一次,那么这种情况下就可以省略掉该类的定义,而改为使用匿名内部类。

    2. 格式:接口名称 对象名 = new 接口名称(){

      ​ // 覆盖重写所有抽象方法

      }; 对比一下多态的格式:

      接口名称 对象名 = new 实现类名称();

1.2.13 包装类
  1. 定义:使用一个类,把基本类型的数据装起来,并在类中定义一些方法,这个类叫包装类。
  2. 列举:
基本类型 包装类(引用类型)
byte    Byte
short   Short
int     Integer
long    Long
float   Float
double  Double
char    Character
boolean Boolean

注意:如果希望向集合ArrayList中存储基本类型数据,必须使用基本类型对应的包装类。

  1. 装箱与拆箱

    1. 装箱:从基本类型转换为对应的包装类对象。
      1. 构造方法:Integer(int value)
      2. 静态方法:valueOf(int value)
    2. 拆箱:从包装类对象转换为对应的基本类型。
      1. 成员方法:int intValue()
  2. 自动装箱与自动拆箱:基本类型的数据和包装类之间可以自动的相互转换

  3. 基本数据类型与字符串类型之间的转换:

    1. 基本类型->字符串:

      1. 基本类型的值+"" (常用)
      2. static String toString(int i):返回一个表示指定整数的String对象(包装类的静态方法)
      3. static String valueOf(int i):返回int参数的字符串表示形式 (String类的静态方法)
    2. 字符串->基本类型:使用包装类的静态方法parseXXX(“数值类型的字符串”)

      Integer类:static int parseInt(String s)

      Double类:static double parseDouble(String s)

第二章 常用API

2.1 String类

  1. 特点:

    1. 字符串的内容永不可变。(重点
    2. 字符串是可以共享使用的。
    3. 字符串效果上相当于是char[]字符数组,但是底层原理是byte[]字节数组。
  2. 创建字符串的常见3+1种方式:

    1. 三种构造方法:
      1. public String():创建一个空白字符串,不含有任何内容
      2. public String(char[] array):根据字符数组的内容来创建对应的字符串
      3. public String(byte[] array):根据字节数组的内容来创建对应的字符串
    2. 一种直接创建:String str = “hello”;
  3. 常量池:程序中直接写上的双引号字符串,就在字符串常量池中。(new出来的字符串不在常量池中)

  4. 常用方法:

    // == 是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:
    public boolean equals(Object obj)
    public boolean equalsIgnoreCase(String str)
    // 字符串获取相关内容的方法:
    public int length(): 获取字符串当中含有的字符个数,即字符串长度
    public String concat(String str): 将当前字符串和参数字符串拼接后成为返回值新的字符串
    public char charAt(int index): 获取指定索引位置的单个字符。(索引从0开始)
    public int indexOf(String str): 查找参数字符串在本字符串中首次出现的索引位置,没有返回-1
    // 字符串的截取方法:
    public String substring(int index): 截取从参数位置一直到字符串末尾,返回新字符串
    public String substring(int begin,int end): 截取从begin开始,一直到end结束,左闭右开
    // 字符串中与转换相关的方法:
    public char[] toCharArray(): 将当前字符串拆分成为字符数组作为返回值
    public byte[] getBytes(): 获得当前字符串底层的字节数组作为返回值
    public String replace(CharSequence oldString,CharSequence newString): 将所有出现的老字符串替换成为新的字符串,返回替换之后的新字符串作为结果 (CharSequence就是说可以接受字符串类型)
    // 分割字符串的方法:  使用\\ 来对 * ^ | . 等特殊符号进行转义
    public String[] split(String regex): 按照参数的规则,将字符串切分成为若干部分
    // 字符串判断相关内容的方法:
    public boolean startsWith(String prefix): 判断一个字符串是否以参数字符串开头
    public boolean constains(String prefix): 判断一个字符串是否包含参数字符串
    

2.2 Arrays类

  1. 定义:是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作

  2. 基本使用:

    public static String toString(数组): 将数组变成字符串(格式:[元素1,元素2,...]
    public static void sort(数组): 按照默认升序(从小到大)对数组的元素进行排序
    /*
     1. 如果是数值,sort默认按照升序从小到大
     2. 如果是字符串,sort默认按字母升序
     3. 如果是自定义的类型,那么自定义的类需要有Comparable或者Comparetor接口的支持(后面学)
    */ 
    

2.3 Math类

  1. 定义:是一个与数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作

  2. 基本使用:

    public static double abs(double num): 获取绝对值(此参数可以是intfloat...,返回值类型相对应)
    public static double ceil(double num): 向上取整
    public static double floor(double num): 向下取整
    public static long round(double num): 四舍五入
    

2.4 Object类

  1. 概述:Object类是类层次结构的根类。每个类都使用Object作为父类。

  2. toString方法:

    1. public String toString():返回该对象的字符串表示
    2. 看一个类是否重写了toString方法,直接打印这个类对应对象的名字即可(重点
      1. 如果没有重写toString方法,那么打印的就是对象的地址值。
      2. 如果重写了toString方法,那么就按照重写的方式打印。
  3. equals方法:

    1. public boolean equals(Object obj):指示其他某个对象是否与此对象相等。(默认比较地址值)

    2. 重写equals方法,用来比较两个对象的内容

      public boolean equals(Object obj) {
          if(obj instanceof Person){
              // 向下转型
              Person p = (Person) obj;
              // 比较两个对象的属性
              boolean b = this.name == p.name && this.age == p.age;
              return b;
          }
          return false;
      }
      
  4. Objects类:

    1. public static boolean equals(Object a,Object b):主要用来避免空指针异常的情况

    2. 使用

      String a = "hello";
      String b = "hello";
      boolean b = Objects.equals(a,b);  // true
      

    补充:hashCode()方法:返回该对象的哈希码值(十进制数)(set和map集合中的元素不能重复的时候使用)

2.5 日期时间类

2.5.1 Date类
  1. 定义:表示日期和时间的类,精确到毫秒。
  2. 构造方法:
    1. 空参数:Date date = new Date() 获取当前系统的日期和时间
    2. 带参数:Date date = new Date(毫秒值) 把毫秒值转换为Date日期
  3. 成员方法:
    1. public long getTime():将Date日期转换为毫秒值
      1. 注意:这个方法的作用等同于System.currentTimeMills()
2.5.2 DateFormat类
  1. 定义:是是日期/时间格式化子类的抽象类SimpleDateFormat 是直接子类
  2. 子类的构造方法:
    1. SimpleDateFormat(String pattern):用给定的模式和默认语言环境的日期格式符号构造
    2. 模式:y-年 M-月 d-日 H-时 m-分 s-秒 例如:“yyyy-MM-dd HH:mm:ss”
    3. 注意:模式中的字母不能更改,连接模式的符号可以改变。
  3. 作用:
    1. 格式化(日期 -> 文本):
      1. public final String format(Date date):按照指定的模式,把Date日期格式化为字符串
    2. 解析(文本 -> 日期):
      1. public Date parse(String source) throws ParseException: 把字符串解析为Date日期
      2. 异常问题:如果字符串和构造方法的模式不一样,那么程序就会抛出异常,调用一个抛出了异常的方法,就必须处理这个异常,要么throws继续抛出这个异常,要么try catch自己处理

2.6 Calendar类

  1. 定义:日历类,出现在Date之后,替换掉了很多Date的方法,该类将所有可能用到的时间信息封装到静态成员变量,方便获取。日历类是用来获取各个时间属性的。(抽象类)
  2. 创建对象:
    1. Calendar类无法直接创建对象使用,里面有一个静态方法叫getInstance(),该方法返回了子类对象。
    2. 格式:Calendar c = Calendar.getInstance();
  3. 常用方法:
    1. public int get(int field):返回给定日历字段的值
    2. public void set(int field,int value):将给定的日历字段设置为给定值
      1. 同时设置年月日:c.set(2020, 8, 8);
    3. public abstract void add(int firld,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量
    4. public Date getTime():返回一个表示此Calendar的时间值(毫秒)的Date对象。
  4. 字段:YEAR MONTH(0-11) DAY_OF_MONTH/DATE HOUR MINUTE SECOND (都是静态变量,可通过类.静态变量获取)

2.7 System类

  1. 提供了大量的静态方法
    1. long currentTimeMills():返回当前时间(毫秒)。
    2. void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):将数组中指定的数据拷贝到另一个数组中。

2.8 StringBuilder类

  1. 定义:字符串缓冲区,可以提高字符串的操作效率(看成一个长度可以变化的字符串),底层也是一个byte数组,但是没有被final修饰(可以改变长度)。
  2. 构造方法:
    1. StringBuilder():构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
    2. StringBuilder(String str):构造一个字符串生成器,并初始化为指定的字符串内容。
  3. 常用方法
    1. public StringBuilder append(…):添加任意类型数据的字符串形式,并返回当前对象(不用接收返回值),可采用链式编程。
      1. 链式编程:方法返回值是一个对象,可以继续调用方法。
    2. public String toString():将当前StringBuilder对象转换为String对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值