枚举和抽象类和接口

分包思想
如果将所有的类文件都放在同一个包下,不利于管理和后期维护。所以,对于不同功能的类文件,可以放在不同的包下进行管理

  1. 包的概述和定义
    问题:
    1.创建包时,包的命名规则有怎样的要求?
    2.Java中是用哪一个关键字表示包?
    3.使用idea时,是否需要手动给一个类定义包?
    包本质上是文件夹,里面放类文件。如果所有的类文件放在一个包下,不方便管理
    包的定义
    使用package定义包(import关键字是导入包)
    多级包用“.”隔开,都是小写字母
    多级包名,是企业网址翻转,例如:com.itheima.*就是我们写的包名
    不用手动给类定义包,使用idea生成
    思考:为什么包名推荐用公司域名,并且还是反写的形式?
    公司域名具有唯一性,并且你所开发的是企业级应用程序,只属于企业
    当你域名反写的时候,你的代码会直接放在相关文件夹下,如果不反写,所有的代码都在com下
  2. 包的注意事项和类访问
    问题:
    1.在类中,使用package定义包时,需要注意哪些问题?
    2.在一个类中访问另一个类,什么时候不需要导包?
    3.全类名由哪些部分组成,一般出现的场景是什么?
    包的注意事项:
    package语句必须是程序的第一条可执行语句
    package语句在一个java文件中只能有一个
    如果没有package,默认表示无包名
    类与类之间的访问
    同一个包下:不需要导包
    不同的包下:
    import导包
    通过全类名(包名+类名)访问:代码中同一个类下,要访问两个包下名字相同的类时
    import、package、class三个关键字的摆放位置存在顺序关系
    package必须是程序的第一条可执行的代码
    import需要写在package下面
    class需要在import下面
    权限修饰符
    问题:
    1.在java中,权限修饰级别有几种,分别对应哪些关键字?
    2.对于没有用任何权限修饰符修饰的方法,能否在不同的包下被访问?
    3.对于使用protected修饰的方法,该类的子类是否在任何包下都可以访问这个方法?

test1包
/**

  • 1.在test1包下创建一个Fu类,定义默认和保护两种级别的方法
  • 2.分别在不同包下写一个子类继承Fu类,去调用父类的两个方法
  • 3.分别在不同包下写测试类验证
    */
    public class Fu {
    void show() {
    System.out.println(“默认权限 ---- show方法”);
    }

    protected void print() {
    System.out.println(“protected权限 ---- print方法”);
    }
    }

    public class Zi extends Fu {
    // 同一个包下, 被子类访问
    public void method() {
    super.show();
    }
    }

    public class Test {
    public static void main(String[] args) {
    // 同一个包下, 无关类访问
    Fu f = new Fu();
    f.show();
    }
    }
    test2包
    import com.itheima.test1.Fu;

    public class Son extends Fu {
    // 不同包下, 被子类访问
    public void method(){
    // super.show();
    super.print();
    }
    }

    public class Test {
    public static void main(String[] args) {
    // 不同包下, 被无关类访问
    Fu f = new Fu();
    //f.show();
    //f.print();
    }
    }
    final
    问题:
  1. final关键字有什么作用?

  2. final关键字可以修饰哪些内容?

  3. 被final修饰的变量如果是引用数据类型,有什么特点?
    fianl关键字的作用:
    final关键字代表最终的意思,可以修饰成员方法,变量,类
    final修饰的特点:
    fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)
    final修饰方法:该方法不能被重写
    final修饰变量:该变量不能再次赋值
    变量是基本类型,不能改变的是值
    变量是引用类型,不能改变的是地址值,但地址里面的内容是可以改变的
    举例:
    public static void main(String[] args){
    final Student s = new Student(23);
    //s = new Student(24); // 编译错误
    s.setAge(24); // 正确
    }
    命名规范:如果是一个单词,所有字母大写,如果是多个单词,所有字母大写之外,还需要单词间用下划线分隔,例如:final int MAX_VALUE = 20;
    练习:以下代码哪些是有问题的,为什么?
    public class Student {
    final int age;

    public void setAge(int age) {
    this.age = age;
    }
    }
    /有问题,因为普通方法是在对象出现之后,才有可能被调用,不调用,这个值不能赋值。被final修饰的变量必须赋值。/
    public class Student {
    final int age=18;

    public void setAge(int age) {
    this.age = age;
    }
    }
    //有问题,被final修饰的变量不能再次赋值
    public class Student {
    final static int age;

    public static void setAge(int a) {
    age = a;
    }
    }
    /*
    静态方法在类加载的时候就会加载信息,但是不是说方法里面的内容会执行。
    方法不调用不能执行。不执行的话,这个变量没有值。被final修饰的变量必须赋值。
    */
    public class Student {
    final int age;

    public Student() {
    age = 18;
    }
    }
    //正确
    常量
    概念:在程序运行期间,其值不能发生改变的量
    作用:用于做系统的配置信息,方便程序的维护,同时也能提高可读性
    命名规范:如果是一个单词,所有字母大写,如果是多个单词,所有字母大写之外,还需要单词间用下划线分隔,例如:final double PI= 3.14;
    宏替换:
    当定义final变量时就为该变量指定了初始值,并且这个初始值在编译时就可以确定,那么这个变量就是“宏变量”
    编译期会把程序中所有用到这个变量的位置直接替换成该变量的值
    枚举
    为了间接的表示一些固定的值,Java就给我们提供了枚举
    是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内

  4. 定义格式
    格式
    public enum s {
    枚举项1,枚举项2,枚举项3;
    }
    注意: 定义枚举类要用关键字enum
    示例代码
    // 定义一个枚举类,用来表示春,夏,秋,冬这四个固定值
    public enum Season {
    SPRING,SUMMER,AUTUMN,WINTER;
    }

  5. 特点
    所有枚举类都是Enum的子类
    我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
    每一个枚举项其实就是该枚举的一个对象
    枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
    枚举类可以有构造器,但必须是private的,它默认的也是private的

  6. 作用
    使用场景:用作信息标志和分类
    优势:
    常量虽然可以实现可读性,但是入参值不受约束,代码相对不够严谨
    枚举代码可读性好,入参约束严谨,建议使用!
    案例:
    public class Demo {
    public static void main(String[] args) {
    /**
    * 需求:调用发短信的方法,传入对应的节日,即可打印节日短信祝福语
    * 方法参数使用字符串类型声明,有什么不足?怎么改进?
    */

    }

    public static void sendMessage(String holiday) {
    switch (holiday) {
    case “国庆节”:
    System.out.println(“莉莉,国庆节快乐!”);
    break;
    case “劳动节”:
    System.out.println(“菲菲,劳动节快乐!”);
    break;
    case “儿童节”:
    System.out.println(“娜娜,儿童节快乐!”);
    break;
    case “春节”:
    System.out.println(“缇娜,国庆节快乐!”);
    break;
    }
    }
    }
    抽象类

  7. 抽象类入门
    问题:
    1.抽象方法具有什么特点?
    2.在什么条件下,一个类必须声明为抽象类?
    概述:
    抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法
    抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
    抽象方法的定义格式:
    //方法需要用abstract关键字修饰,方法没有方法体
    public abstract 返回值类型 方法名(参数列表);
    抽象类的定义格式:
    //使用abstract关键字修饰类
    public abstract class 类名{}
    代码案例:
    需求:定义猫类(Cat)和狗类(Dog)
    猫类成员方法:eat(猫吃鱼)drink(喝水…)
    狗类成员方法:eat(狗吃肉)drink(喝水…)
    实现步骤:
    猫类和狗类中存在共性内容,应向上抽取出一个动物类(Animal)
    父类Animal中,无法将 eat 方法具体实现描述清楚,所以定义为抽象方法
    抽象方法需要存活在抽象类中,将Animal定义为抽象类
    让 Cat 和 Dog 分别继承 Animal,重写eat方法
    测试类中创建 Cat 和 Dog 对象,调用方法测试
    代码实现:
    public abstract class Animal {
    public abstract void eat();

    public void drink() {
    System.out.println(“喝水”);
    }
    }

public class Dog extends Animal{
@Override
public void eat() {
System.out.println(“狗吃屎”);
}
}

public class Cat extends Animal{
@Override
public void eat() {
System.out.println(“猫吃鱼”);
}
}

public class TestAnimal {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.drink();
System.out.println(“-------------”);
Cat cat = new Cat();
cat.eat();
cat.drink();
}
}
/**

  • 根据初高中的数学知识,不同图形的样式和计算周长的方式都不一样,例如正方形和圆形
  • 定义一个抽象类Shape
  • 行为:
    
  •      计算周长 celPerimeter
    
  •      返回形状 getType
    
  • 定义一个正方形类Square
  •  属性:
    
  •      边长 side
    
  •  行为:
    
  •      设置边长 setSide
    
  •      计算周长 celPerimeter
    
  •      返回形状 getType
    
  • 定义一个三角形类Circle
  •  属性:
    
  •      半径 radius
    
  •  行为:
    
  •      设置半径 setRadius
    
  •      计算周长 celPerimeter
    
  •      返回形状 getType
    
  • 根据高中所学几何图形基本知识,完善正方形和圆形类的功能,并在测试类中测试

*/
public abstract class Shape {
public abstract double celPerimeter();

public abstract String getType();

}

public class Square extends Shape {
int side;

public void setSide(int side) {
    this.side = side;
}

@Override
public double celPerimeter() {
    return side * 4;
}

@Override
public String getType() {
    return "正方形";
}

}

public class Circle extends Shape {
int radius;

public void setRadius(int radius) {
    this.radius = radius;
}

@Override
public double celPerimeter() {
    //Math.PI是得到圆周率,是一个小数,所以最后的结果要强转成int类型
    return  (2 * Math.PI * radius);
}

@Override
public String getType() {
    return "圆形";
}

}

public class TestShape {
public static void main(String[] args) {
Square square = new Square();
square.setSide(3);
double perimeter1 = square.celPerimeter();
System.out.println(square.getType() + “的周长是:” + perimeter1);

    Circle circle = new Circle();
    circle.setRadius(2);
    System.out.println(circle.getType() + "的周长是:" + circle.celPerimeter());
}

}
2. 抽象类的注意事项
问题:
1.在程序中能否使用new关键字调用抽象类的构造方法?
2.在一个抽象类当中,能不能不定义抽象方法?
3.抽象类是否可以定义构造方法?
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
现在没有,不代表以后没有,未雨绸缪
抽象类不能实例化
如果可以实例化,调用抽象方法,没法执行功能。抽象方法没有方法体
可以有构造方法
因为子类的构造方法中有super();
抽象类的子类如果继承抽象类,抽象类有抽象方法的话
要么重写抽象类中的所有抽象方法
要么是抽象类(不推荐)
提问:
abstract能不能和static同时修饰方法?为什么?
抽象方法要求要重写,但是静态方法不能被重写
abstract能不能和final同时修饰方法?为什么?
抽象方法要求要重写,但是final方法不能被重写
3. 模板设计模式
生活中的模板:
短信模板:

情书模板:

问题:
1.设计模式的引入,对于代码编写有什么好处?
2.模板设计模式的优势是什么?
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
模板设计模式:把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法
让使用模板的类(继承抽象类的类)去重写抽象方法实现需求
模板设计模式的优势:
模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可
代码案例:
作文模板类:
/*
作文模板类
*/
public abstract class CompositionTemplate {

public final void write(){
    System.out.println("<<我的爸爸>>");
	//1.是希望调用子类的特有方法,但是子类如何记得写这个特有方法呢?
    //2.就给抽象类定义一个抽象方法,这样子类就必须重写
    body();

    System.out.println("啊~ 这就是我的爸爸");

}

public abstract void body();

}
实现类:
//3.子类继承父类
public class Tom extends CompositionTemplate {
//4.必须重写抽象方法,实现自己特异性的功能
@Override
public void body() {
System.out.println("那是一个秋天, 风儿那么缠绵,记忆中, " +
“那天爸爸骑车接我放学回家,我的脚卡在了自行车链当中, 爸爸蹬不动,他就站起来蹬…”);
}
}
测试类:
public class Test {
public static void main(String[] args) {
Tom t = new Tom();
//5. write方法是从父类继承过来直接使用的
//6. 在write方法内部,调用的body方法是属于子类自己的
t.write();
}
}
接口

  1. 介绍
    生活中的接口:

Java中继承也可以给子类制定规则,但是:

问题:
1.在什么情况下,就可以使用接口优化代码?
2.接口存在的意义是什么?
介绍:
当一个类中的所有方法都是抽象方法的时候,就可以将其定义为接口
接口也是一种引用数据类型,它比抽象类还要抽象
Java中接口存在的两个意义
用来定义规范
用来做功能的拓展

  1. 定义和特点
    问题:
    1.在java中,使用什么关键字代表接口?
    2.接口是引用数据类型,那是否能够对接口进行实例化?
    3.一个类是否可以和多个接口产生联系?
    接口用关键字interface修饰
    public interface 接口名 {}
    类实现接口用implements表示
    public class 类名 implements 接口名 {}
    接口不能实例化
    我们可以创建接口的实现类对象使用
    接口的实现类
    要么重写接口中的所有抽象方法
    要么实现类也是抽象类
    一个类可以实现多个接口
    //练习一:掌握接口的定义和特点
    //1.使用接口的格式创建两个接口,分别是Inter1和Inter2
    //2.分在两个接口中各自定义一个方法,分别是study()和print()方法
    //3.在测试类TestInterface中,创建接口Inter1的对象,看代码是否有问题
    //4.创建一个类InterImpl,实现Inter1接口
    //5.在测试类TestInterface中,测试实现类的方法使用
    //6.让InterImpl继续实现Inter2接口,查看代码是否有问题
    //7.在测试类中测试InterImpl的方法使用
    //8.如果既想让InterImpl实现接口Inter2,又不想重写Inter2的抽象方法,该如何处理?
    /**
  • 练习二:
  • 利用接口做参数,写个计算器,能完成加减乘除运算。
  • (1)定义一个接口Compute含有一个方法int computer(int n, int m)
  • (2)设计四个类分别实现此接口,完成加减乘除运算
    */
    public interface Compute {
    public abstract int computer(int n, int m);
    }
    public class Test02 {
    public static void main(String[] args) {
    Jia jia = new Jia();
    System.out.println(jia.computer(2, 3));
    Jian jian = new Jian();
    System.out.println(jian.computer(3, 2));
    Cheng cheng = new Cheng();
    System.out.println(cheng.computer(2, 3));
    Chu chu = new Chu();
    System.out.println(chu.computer(6, 3));
    }
    }

//加
class Jia implements Compute {

@Override
public int computer(int n, int m) {
    return n + m;
}

}

//减
class Jian implements Compute {

@Override
public int computer(int n, int m) {
    return n - m;
}

}

//除
class Chu implements Compute {

@Override
public int computer(int n, int m) {
    return n / m;
}

}

//乘
class Cheng implements Compute {

@Override
public int computer(int n, int m) {
    return n * m;
}

}
3. 接口中的成员特点
问题:
1.在接口中定义的成员变量,实现类是否可以给这个变量重新赋值?
2.是否能够在接口中定义这个接口的构造方法?
3.在JDK8以下版本,接口中的方法都默认是什么方法?
成员特点
成员变量
只能是常量
默认修饰符:public static final
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
成员方法
只能是抽象方法
默认修饰符:public abstract
关于接口中的方法,JDK8和JDK9中有一些新特性,后面再讲解
/**

  • 1.定义一个接口ShapeInter,用来制定相关图形计算的规范
  •  属性:
    
  •      圆周率PI:3.1415927
    
  •  行为:
    
  •      计算周长 double celPerimeter();
    
  •      计算面积 double celArea();
    
  •      获取类型 String getType();
    
  • 2.定义圆形类,实现接口,并重写相应方法
  • 3.定义正方形类,实现接口,并重写相应方法
  • 4.在测试类中验证实现类的方法效果
  • 5.接口中的圆周率可以在实现类中更改其值为3.14吗?

*/
public interface ShapeInter {
//圆周率是直接要提供给别人用,而且任何人用都是这个值,这个值也不会改变
double PI = 3.1415927;

//计算周长 double celPerimeter();
public abstract double celPerimeter();

public abstract double celArea();

public abstract String getType();

}

class Circular implements ShapeInter {
double radius;

public void setRadius(double radius) {
    this.radius = radius;
}

@Override
public double celPerimeter() {
    return 2 * PI * radius;
}

@Override
public double celArea() {
    return PI * radius * radius;
}

@Override
public String getType() {
    return "圆形";
}

}

public class TestShapeInter {
public static void main(String[] args) {
Circular circular = new Circular();
circular.setRadius(3);
System.out.println(circular.getType()+“的周长是:”+circular.celPerimeter());
System.out.println(circular.getType()+“的面积是:”+circular.celArea());
}
}
4. JDK8版本中成员的特点:默认方法
问题:
1.为什么JDK8要针对接口引入默认方法?
2.如果实现类要重写默认方法,需要注意什么?
3.如果实现类实现的两个接口中,有相同的默认方法,实现类该如何处理?
格式:public default 返回值类型 方法名(参数列表) { }
作用:解决接口升级的问题
范例:
public default void show3() {

}
注意事项:
默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字
接口中,public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同的默认方法声明,子类就必须对该方法进行重写
案例:支付宝和美团
支付宝:

美团:

支付宝和美团都有卡包功能,支付宝的卡包有优惠券和车票,美团的卡包只有优惠券
定义一个接口Function,在里面定义抽象方法card(),代表卡包功能
在接口Function定义一个默认方法scan(),实现扫码功能,实现类对象可直接使用
美团有骑车功能,请在接口Function中定义合适的方法
定义一个美团类Meituan实现该接口,重写相应方法
在测试类中创建美团类对象,分别调用扫码和骑车功能
public class FunctionTest {
public static void main(String[] args) {
Meituan meituan = new Meituan();
meituan.rideBike();
Alipay alipay = new Alipay();
alipay.card();
}
}

//1.定义接口,去规范支付宝和美团的功能
interface Function{
//支付宝和美团的卡包功能,实现是不一样的,所以是抽象方法
public abstract void card();

//支付宝和美团的扫码是一样的,这种情况下,可以定义默认方法,直接给实现类使用
public default void scan() {
System.out.println(“扫码,一分钱也没有,你个穷*”);
}

//美团中有骑车功能,这个骑车功能应该定义成默认方法,因为支付宝当中没有,如果定义成抽象
//会导致支付宝也拥有骑车
public default void rideBike() {
System.out.println(“扫码骑车”);
}
}

//2.定义美团实现类,去实现这个接口
class Meituan implements Function{

@Override
public void card() {
System.out.println(“我只有优惠券”);
}
}

class Alipay implements Function {

@Override
public void card() {
System.out.println(“支付宝的卡包有优惠券还有会员卡还有电影票”);
}
}

5. JDK8版本中接口成员的特点:静态方法
问题:
1.接口中的静态方法能不能被其实现类对象调用?
2.接口的静态方法中,static关键字能否被省略?
3.接口中静态方法的主要作用是什么?
格式:public static 返回值类型 方法名(参数列表) { }
范例:
public static void show() {
}
注意事项:
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
静态是属于类的,无法被重写
public可以省略,static不能省略
//练习:掌握接口中静态方法的定义和注意事项
public interface Inter {

public static void staticMethod1() {
System.out.println(“接口中的静态public方法”);
}

static void staticMethod2() {
System.out.println(“接口中的静态方法public可以省略不写”);
}

/*
void staticMehtod3(){
System.out.println(“接口中的静态方法,static不能省略”);
}
*/

}

//接口实现类
class InterImpl implements Inter{
//接口中静态方法无法被重写
//@Override
public static void staticMethod1() {
System.out.println(“实现类尝试重写接口的静态方法”);
}

}

public class TestInter {
public static void main(String[] args) {
InterImpl interImpl = new InterImpl();
//调用的是自己的静态方法,不是接口的
interImpl.staticMethod1();
//接口的静态方法,无法被其实现类对象调用
//interImpl.staticMethod2();
//接口的静态方法,只能被“接口名.方法名”调用
Inter.staticMethod1();
Inter.staticMethod2();
}
}
6. JDK9版本中接口成员的特点:私有方法
问题:
1.接口中为什么要引入私有方法,它的作用是什么?
2.在接口中是否能够同时使用private和default修饰方法?
私有方法产生原因
Java 9中新增了带方法体的私有方法,这其实在Java 8中就埋下了伏笔
Java 8允许在接口中定义带方法体的默认方法和静态方法
当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性
定义格式
格式1:private 返回值类型 方法名(参数列表) { }
范例1
private void show() {
}
格式2:private static 返回值类型 方法名(参数列表) { }
范例2
private static void method() {
}
注意事项
默认方法可以调用私有的静态方法和非静态方法
接口中的静态方法只能调用静态方法
//接口
public interface Inter {
public default void start() {
System.out.println(“start方法执行了…”);
log();
}

public default void end() {
System.out.println(“end方法执行了…”);
log();
}

private void log(){
System.out.println(“日志记录 ( 模拟 )”);
}

private static void check(){
System.out.println(“权限校验 ( 模拟 )”);
}

public static void open() {
check();
System.out.println(“open方法执行了”);
}

public static void close(){
check();
System.out.println(“close方法执行了”);
}
}

class InterImpl implements Inter {

}

public class TestInterface {
public static void main(String[] args) {
InterImpl ii = new InterImpl();
ii.start();
ii.end();

Inter.open();
Inter.close();
}
}
接口的使用思路:
如果发现一个类中所有的方法都是抽象方法,那么就可以将该类,改进为一个接口;
涉及到了接口大面积更新方法,而不想去修改每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法;
希望默认方法调用的更加简洁,可以考虑设计为static静态方法(去掉default关键字);
默认方法中出现了重复代码,可以考虑抽取出一个私有方法(去掉default关键字
7. 类和接口的关系
问题:
1.一个类的父类和实现的接口有相同的方法,那么该类调用这个方法,会调用谁的?
2.如果一个接口的两个父接口存在相同的默认方法,子接口需要做什么处理吗?
类与类的关系
继承关系,只能单继承,但是可以多层继承
类与接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口与接口的关系
继承关系,可以单继承,也可以多继承
注意事项:
如果一个类的父类和所实现的接口中有相同的方法,默认调用的是父类的方法
如果两个接口中有同名的默认方法,其实现类或子接口都必须重写该方法
代码练习:
/**

  • 目标:掌握接口和接口、类和接口之间的关系
  • 1.定义接口Inter1和Inter2,在里面分别定义抽象方法method1和默认方法method2
  • 2.定义一个接口继承Inter1和Inter2,观察效果
  • 3.定义一个Fu类,在类中定义一个method2方法
  • 4.定义一个Zi类,继承Fu类,并且实现Inter1接口,重写相应方法
  • 5.在测试类中创建Zi类对象,调用method2方法,观察效果
  • 6.定义一个Son类,同时实现Inter1和Inter2,观察效果
    */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值