面向对象编程OOP

面向对象编程OOP——Java的核心思想

1.初始面向对象

(1)面向过程&面向对象
  • 面向过程:线性思维(微观操作、流程)
  • 面向对象:分类的思维方式(宏观、框架)
    在这里插入图片描述
  • 属性+方法=一个类
(2)面向对象OOP

在这里插入图片描述

  • 抽象:抽象出共同部分,剥离出来
  • 特征:封装、继承、多态
  1. 封装:封装代码数据,对外提供一个接口来访问
  2. 继承:子类继承父类的所有东西
  3. 多态:同一个方法表现出不同形态

2.方法回顾和加深

(1)方法的定义
  1. 修饰符
  2. 返回类型
  3. break 和 return 的区别(强调)
    break: 跳出 switch,结束循环
    return:结束方法,返回一个结果。这个结果可能为空
  4. 方法名:注意规范就ok,并且要见名知意。驼峰命名规范,开头小写,后面每个单词开头大写
  5. 参数列表:(参数类型 参数名)…
  6. 异常抛出:后面讲解
    在这里插入图片描述
    在这里插入图片描述
(2)方法的调用
  1. 静态方法:static
    调用时:类名.方法名
    在这里插入图片描述
  2. 非静态方法
    先通过new关键字实例化这个类
    然后创建对象:对象类型 对象名 = 对象值
    最后调用:对象名.方法名
    在这里插入图片描述
    a和b都是普通方法或者都是静态方法,他们之间是可以互相调用的
    如果a是静态方法,而b是普通方法,则a不能调用b
    原因:static 的a方法是和类一起加载的,有了类就有方法,时间片特别长;但是b方法跟对象有关,类实例化为对象之后才存在。存在的东西调用还不存在的东西,所以会报错
    在这里插入图片描述
  3. 形参和实参:实际参数和形式参数的类型要对应
    在这里插入图片描述
  4. 值传递和引用传递(注意例子对比)
    Java中都是值传递
    在这里插入图片描述
    引用传递:一个对象
    在这里插入图片描述
  5. this关键字:继承和多态的时候再说

3.对象的创建分析

(1)类与对象的关系
  • 类是一个模板,是抽象的。
  • 对象是一个实例,是具体的。
    在这里插入图片描述
(2)创建与初始化对象

在这里插入图片描述

1)创建对象
  • 一个项目应该只存在一个main方法
    在这里插入图片描述
  • 一个类只有属性和方法
  • 类是抽象的,要进行实例化。类实例化后会返回一个自己的对象!
  • 同一个类可以有不同的对象,但有共同的属性
    在这里插入图片描述
2)构造器
  • 一个类即使什么都不写,也会存在一个方法(构造方法,构造器)
  • 不写的话则会默认生成
  • 也可以显式的定义构造器:与类名相同,且没有返回值的无参构造
  • 用new关键字实例化了一个对象Person person = new Person();时,其实已经包含了public Person(){ }
    在这里插入图片描述
构造器能干吗:

在这里插入图片描述

有参构造
  • 一旦定义了有参构造,要想通过无参构造去创建对象的话Person person = new Person();,无参构造就必须显式定义,否则无效。
    在这里插入图片描述
  • 总结:所以在正常情况下,如果定义了有参构造,就默认把无参构造写在上面,留个空就行
    在这里插入图片描述
    在这里插入图片描述
    下面的 public Person(String name) 是重载,上面的是 public Person() 是默认的构造器
  • 快捷键:Alt + insert 后弹出Generate,选择第一个construct ,弹出一个窗口,有个name,点OK,就会自动生成
public Person(String name){
        this.name = name;
    }

若想要无参,Alt + insert 后弹出Generate,选择第一个construct ,弹出一个窗口,选择SelectNone,就会生成

    public Person(){
    }

在这里插入图片描述
若定义了多个属性,也可以快捷生成多个属性对应的有参构造
在这里插入图片描述
在这里插入图片描述

  • 总结:
  1. 使用new关键字,本质是在调用构造器
  2. 用来初始化值
  • 注意点:定义了有参构造之后,如果想要使用无参构造,必须显式定义一个无参的构造
  • this:代表的是当前类 this.XX表示的是当前类的属性 this.XX = 等号后面的那个一般是参数传进来的
  • 注意:如何在IDEA中打开out目录
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 目录结构和代码文件一样,里面都是编译好的 class 文件

*创建对象内存分析

实际内存图会复杂很多,还有类加载,class对象什么的。这里的内存分析专门为了理解
举例的代码如下:
在这里插入图片描述

  1. 首先有一个Application类。里面有一个main方法,还有字符串常量值(旺财),年龄只是一个数字,不是常量值。
  2. 然后程序开始main()方法, 把main压入栈底(一般来说,最后main方法执行完之后从栈中出来,程序就结束)
  3. debug进行下一步,进行到Pet dog = new Pet(); ,要去加载Pet这个类。
  4. Pet类中有属性字段name、age,还有方法shout()。(还有常量值,这里没有)当前name为null,age为0
    在这里插入图片描述
  5. 通过Pet这个类模板生成一个dog对象,栈中多了一个dog对象(只是个引用变量名)。真正的对象在堆中,new了一个Pet,name为null,age为0,shout()调用了下面Pet类的shout()。
    在这里插入图片描述
  6. 再走下一步执行dog.name = “旺财”; dog.age = 3; ,把Application中的name和age赋值给dog对象
    在这里插入图片描述
    在这里插入图片描述
  7. 如果此时又new一个cat对象。则此时栈中又多了一个 cat 引用变量名。真正的对象在堆中,new了一个Pet,name为null,age为0,shout()调用了下面Pet类的shout()。然后接着重复上述的步骤。
    在这里插入图片描述
    在这里插入图片描述
  • 引用变量真正指向的还是堆中
  • 静态方法区。所有static的东西都在这里。一开始就和类一起加载的.所有的对象都可以直接调用它。
    在这里插入图片描述
  • 总结:左边是栈,右边是堆。堆中有一块特殊区域叫做方法区。方法区也属于堆。堆中一般放具体创建出的对象。而栈里面都是方法和变量的引用。
    因此,同时new的都是Pet,但是产生不一样的对象。因为它产生的是不同区域,地址可能不同,引用变量也不同。
    在这里插入图片描述

简单小结类与对象

1.类与对象

类是一个模板,抽象的。对象是一个具体的实例。

2. 方法(定义和调用!)
3.对象的引用

引用类型:除了八大基本类型之外的都可以叫做引用类型
对象是通过引用来操作的。就是内存图中在栈中的,真实对象是在堆中的

4.对象的属性
  • 别名:字段 field、成员变量
  • 定义了属性,会默认初始化:
    数字 0/0.0 ;
    char u0000 ;
    boolean false ;
    引用类型 null
  • 属性的定义: 修饰符 属性类型 属性名 = 属性值
5.对象的创建和使用
  • 必须使用new关键字创建对象,必须有构造器 Person zhangpipi = new Person();
  • 对象的属性 zhangpipi.name
  • 对象的方法 zhangpipi.sleep()
6.类(类中只有属性和方法)
  • 静态的属性 属性
  • 动态的行为 方法

4.面向对象三大特性(重点)

(1)封装 → 属性私有 privite, get/set

在这里插入图片描述

  • 封装大多数时候是对于属性来的;对方法来说用的比较少。重点是对于属性。这个地方写方法是为了大家理解其实方法是用不了多少封装的。
  • 属性私有:private。 和public相对
    在这里插入图片描述
    在这里插入图片描述
  • 提供一些可以操作这个属性的方法→提供一些 public 的 get、set方法
    get:获得这个数据(属性) set:给这个数据设置值
    没有直接去操作属性,而是通过它提供的一些外部的方法对它进行操作。通过set进行设值,通过get方法进行获取。
    在这里插入图片描述
  • 快捷键 Alt + insert(相当于右击后的Generate): 自动生成 get 和 set 方法.直接选择get and set方法
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    选中你需要对哪个属性生成 get 和 set 方法
    在这里插入图片描述
    在这里插入图片描述
  • 快捷键 输入s1.getAge().sout →就会变成 System.out.println(s1.getAge());
    即输入 输出内容.sout →就会变成 System.out.println(输出对象);
封装的意义
  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节。调用者不知道类里面干了什么
  3. 统一接口。所有的方法都是 get 和 set 。形成了规范,用户调用的接口就是这个
  4. 提高了系统的可维护性
    在这里插入图片描述
* 插播一句,方法的重载

eg :println。点进去看源码 。方法重载,同名不同参数
在这里插入图片描述

  • 方法名和参数列表要是相同,这个方法一定相同。看方法名和参数列表!!!!!
(2)继承

在这里插入图片描述

  • 一个儿子只能有一个爸爸,一个爸爸可以有多个儿子。
  • 组合关系实例(以后再讲)
    在这里插入图片描述
  • 子类可以继承父类的所有方法。子类继承了父类,就会拥有父类的全部方法!
    在这里插入图片描述
  • 私有的东西是无法继承的。
    在这里插入图片描述
  • 四个优先级修饰符: public 公有的 protected 受保护的 default 默认的 private 私有的
    其中,优先级最高的是 public 。子类继承父类的东西一般都是 public 方法,get 、set 也是。一般属性是私有的。
  • 按照封装的思想,父类的属性也应该设置成私有的,然后给他设置两个公共的方法。
    在这里插入图片描述
  • 快捷键 Ctrl + H :侧边打开继承树,表示继承关系
    在哪个地方点,就出现对应的所有继承关系
    在这里插入图片描述
    在这里插入图片描述
object 类
  • 在Java中,所有的类,都默认直接或者间接继承Object
    即使 Person 中什么都没有,也会有很多方法
    在这里插入图片描述
    可以进入Object中看,String也是继承的Object。在Java中,所有的类,都默认直接或者间接继承Object
    在这里插入图片描述
    显式定义没啥用,正常情况下不写。总之,你写一个类,即使不继承任何东西,他其实也是继承 Object 类的。
    在这里插入图片描述
super(可以对比 this 来学习。一个是父亲,一个是当前的)
  • 分不清谁是谁的 name 或者 print 的话,可以 Ctrl + 左击跳转查看。
  • 属性
    在这里插入图片描述
  • 方法
    在这里插入图片描述
  • 私有的东西无法被继承
    在这里插入图片描述
  • 调用构造器
    在这里插入图片描述
    默认调用了父类的构造器 super()
    调用父类的构造器,必须在子类构造器的第一行
    正常情况下不写这段代码,默认是调用父类的无参构造
    在这里插入图片描述
    如果要调用子类的构造器,也必须在第一行。
    在这里插入图片描述
    所以,调用构造器时,要么调用父类的构造器,要么调用子类的构造器。因为都必须在代码的第一行,必须保证在构造器的第一个。

如果父类没有无参构造,那么子类既不能调用父类的无参构造,自己也不能写无参构造。
在这里插入图片描述
在这里插入图片描述所以必须要有一个无参构造。一个类无论怎么写,只要重写了有参构造,一般就是先把无参构造加上。
如果非要用有参,那子类就得显式写出调用父类的有参构造。不然不写的话就是默认调用父类的无参构造。
在这里插入图片描述

super总结笔记
  • super 注意点:
  1. super 调用父类的构造方法,必须在构造方法的第一个
  2. super 必须只能出现在子类的方法或者构造方法中!(不然在自己的类中调用 super,不然调用到 object 中去了)
  3. super 和 this 不能同时调用构造方法。(因为同时调用的话,它必须保证在第一行,他们肯定有一个报错)
  • 对比 this
  1. 代表的对象不同
    this :本身调用者这个对象(谁调用就是谁)
    super :代表父类对象的引用
  2. 使用的前提不同
    this :没有继承也可以使用
    super :只能在继承条件下才可以使用
  3. 构造方法不同
    this() :本类的构造
    super() :父类的构造
方法重写(重点,关系到多态)→ 只和非静态方法有关

方法重写只和非静态方法有关,因为静态方法在类加载的时候就已经出来了。

  • 重写都是方法的重写,和属性无关
    在这里插入图片描述
  • 静态方法:方法的调用只和左边,集定义的数据类型 有关
    在这里插入图片描述
  • 非静态方法(重写只和非静态方法有关)
    删掉 static 之后(非静态方法),明显多了两个圈。这个O 就代表重载
    在这里插入图片描述
    把子类中的方法删掉,Alt + insert ,里面有一个 Override Method 重写方法
    在这里插入图片描述
    它默认调用的是父类的 test() 方法,super.test(); 。但是我们也可以重写自己的方法。
    在这里插入图片描述
    在这里插入图片描述
    正常情况下,看IDEA有没有出现箭头(那个 O),出现了就是重写了
  • 重写的关键词必须是 public
方法重写总结:

子类继承父类,当父类的方法不适用于子类时候,进行方法重写。

  • 前提:需要有继承关系。而且是子类重写父类的方法!!!(方法,属性不行!)
  1. 方法名必须相同(刚刚Override 它会自动生成)
  2. 参数列表也必须相同(否则就是重载了,而且重载是当前方法)
  3. 修饰符:范围可以扩大,但是不能缩小 public > protected > default >private(子类重写的方法的访问范围要大于等于父类方法的访问范围。但父类的私有方法 private 不能被重写)
  4. 抛出的异常:可以被缩小,但不能扩大。(重写异常抛出范围不能大于父类)
    eg:ClassNotFoundException ------> Exception(大)
  • 重写:子类的方法和父类必须要一致,方法体不同。
  • 为什么需要重写:父类的功能:子类不一定需要,或者不一定满足!
  • 重写的快捷键: Alt + insert ,选择Override
(3)多态

在这里插入图片描述

  • 关键词 instanceof :类型转换。指的是引用类型之间的转换

  • 一个类的实际对象它的类型是确定的,但是指向这个对象的引用类型却可以是任意的(它的父类型或有关系的类),因为父类的引用可以指向子类的类型
    在这里插入图片描述

  • 虽然 new 的是 student ,但是依旧走了父类的方法。因为子类继承了父类的全部方法
    在这里插入图片描述

  • 在子类中重写父类的方法,执行的是子类的方法。因为现在调用的方法是 student,虽然它的类型是 Person。
    在这里插入图片描述

  • 在子类中新增 eat()方法,父类中无该方法,则父类无法调用子类的方法

  • 如果 Person 和 Student 中都有该方法的情况下,只要子类没有重写父类的方法,则调用的是父类的方法。

  • 如果 Person 和 Student 中都有该方法的情况下,只要子类重写了父类的方法,则调用的是子类的方法。在这里插入图片描述

  • 总结:

  • 即对象能执行哪些方法,主要看对象左边的类型,和右边的关系不大

  • Student (子类)能调用的方法都是自己的或者继承父类的!

  • Person (父类型),可以指向子类,但是不能调用子类独有的方法!

  • 通过类型转换可以调用 eat() 方法。Person 转成 Student ,高转低。(后面还会讲)
    在这里插入图片描述

多态注意事项:
  1. 多态是方法的多态,属性没有多态
  2. 父类和子类必须有联系,存在父子关系才可以进行转换。否则会类型转换异常!ClassCastException!
  3. 存在条件:继承关系,方法需要重写,父类的引用指向子类对象,形如 Father f1 = new Son()
    有些方法不能被重写:① static 静态方法,属于类,它不属于实例
    ② final 常量的,无法重写,无法改变(它是在常量池里的)
    ③ private 私有的方法
  • 关键词 instanceof :类型转换。指的是引用类型之间的转换。判断一个对象是什么类型~
instanceof 和类型转换
  • 上面三个满足父子关系,而且是这个类型,所以是 true
  • 所以可以用 instanceof 判断这两个类型是否相似,然后再进行强制转换
  • System.out.println(X instanceof Y); 能不能编译通过!就看 X 和 Y 之间是否存在父子关系
    看 X 所指向的实际类型是否为 Y 的子类型,是否有关系
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 类型之间的转化:
  • 高转低要用强制转换
    在这里插入图片描述
  • 低转高会自动转过去,但是子类转换为父类,可能丢失自己本来的一些方法!
    在这里插入图片描述
总结:
  1. 父类的引用指向子类的对象
  2. 把子类转换为父类,向上转型,不用强制转换,可以直接转化过去
  3. 把父类转换为子类,向下转型,需要强制转换。像之前强制类型转换会丢失精度一样,子类转换为父类,可能丢失自己本来的一些方法!
  4. 方便方法的调用,不用重新 new 一个类,直接降级或者升级就可以调用它的一些其他方法,减少重复的代码!
static 关键字详解
  • 静态属性

  • 静态变量对于类而言,在内存中只有一个,它能被类中的所有实例去共享。
    如果想要很多类去操作他的话,我们就会用static。以后会在多线程中讲到!
    静态变量建议通过类名直接访问
    在这里插入图片描述

  • 静态方法
    非静态方法可以直接去访问这个类中的静态方法,静态方法可以去访问静态方法。
    因为静态的东西和类一起加载,而非静态的还没加载,所以不能直接调用,必须要new一个对象。
    main方法也是一个静态方法。
    在这里插入图片描述

  • 静态代码块
    在Java中,所有的代码都在代码块中,无论是方法还是类
    有时候为了初始化一些东西,我们会用静态代码块,用于加载一些初始化数据

  • 匿名代码块:程序在执行的时候并不能主动调用这些模块。匿名代码块在创建对象时自动就创建了,而且它在构造器之前。因为匿名代码块是和对象一起产生的,所以可以用于赋初始值。

  • 静态代码块:和类一加载时它就直接执行,永久执行一次
    在这里插入图片描述
    在这里插入图片描述
    因此,对象一创建,就会先走匿名代码块,然后走构造方法。如果有静态代码块,则在最开始执行,且只执行一次。
    因为匿名代码块是和对象一起产生的,所以可以用于赋初始值。

  • 静态导入包(一般不这样,只是告诉你java里面东西有很多)
    在这里插入图片描述
    如果不想写Math这个类
    在这里插入图片描述

final之后断子绝孙
  • 通过final修饰的类不能被继承,没有子类
    在这里插入图片描述

5.抽象类和接口

(1)抽象类(了解)

在这里插入图片描述

  • abstract 抽象
  • 抽象方法:只有方法名字,没有方法的实现。可用于约束~有人帮我们实现(只会写大型框架,就直接写约束,其余别人写)
    在这里插入图片描述
  • 抽象类的所有方法,继承了它的子类,都必须要实现它的方法!除非它的子类也是abstract抽象的,则它的子类无需实现,它的子子类就必须要实现。
    在这里插入图片描述
    在这里插入图片描述
  • 抽象类的本质是一个类,类需要继承,逃脱不了extends这个关键字。而extends是单继承的,无法继承多个类具有局限性。
  • 想办法使之能够继承多个类,即多继承。Java中无多继承。
  • 但接口可以多继承!!!!即类是单继承,接口可以实现多继承!(相当于一个插座,是一个约束,约束了可以插什么头,但没有约束什么电器才能插上去)
抽象类的特点:抽象的抽象,即一种约束!
  1. 不能new这个抽象类,只能靠子类去实现它!就是一个约束。所以只能new它的子类对象,如果子类对象没实现它,那就子子类。
    在这里插入图片描述
  2. 抽象类中可以写普通的方法。
  3. 抽象方法必须在抽象类中。(若方法中存在了抽象方法,这个类一定是抽象类)
    思考题:
  4. 抽象类存在构造器。抽象类可以被继承,继承最起码有空参构造器。子类继承父类后,需要通过父类的构造器来实例化,所以抽象类也需要构造器。
  5. 抽象类存在的意义:可以提升开发效率,因为抽象类里面可以写一些公共的方法,这些确实可以达到复用
(2)接口(重点)
  • 接口:比抽象类还要抽象,专业的抽象和约束,实现约束和实现分离。大型公司都是面向接口编程~架构师写好接口,我们就实现接口写里面的方法即可。
    在这里插入图片描述
    在这里插入图片描述
  • 接口中的所有定义的方法其实都是抽象的 即 public abstract。即,你不写,默认就是 public abstract
    在这里插入图片描述
  • 所以以后接口,正常就可以这样写,直接就是:返回值类型 方法名(参数) 。参数根据需要写,也可以无参。
  • 接口也可以定义一些常量和变量,public static final 。一般没什么人会在接口中定义常量
    在这里插入图片描述
  • 接口定义的关键字是 interface ,接口都需要有实现类。一般实现类我们都会用 impl 结尾
  • 关键词 实现:implements
    在这里插入图片描述
  • 类可以实现接口,通过 implements关键字实现接口
  • 实现了接口的类,就必须重写接口中的方法
    在这里插入图片描述
    在这里插入图片描述
  • 利用接口实现了多继承~
  • 与继承的类不同的是,类中会有方法的实现,而接口中只有方法的定义,通过interface来定义
    在这里插入图片描述
接口的作用:
  1. java的接口是一个约束
  2. 定义一些方法,让不同的人去实现。用的一个接口,但是是不同的实现
  3. 接口中的方法都是 public abstract
  4. 接口中的常量都是 public static final
  5. 接口不能被实例化,(抽象类都不能被实例化),接口中没有构造方法
  6. 通过 implements 关键字可以实现多个接口
  7. 实现接口必须要重写接口中的方法

6.内部类及OOP实战

(1)内部类(奇葩)

在这里插入图片描述

  • 成员内部类
  • 通过这个外部类来实例化内部类~
    在这里插入图片描述
  • 内部类访问外部类的私有变量(私有属性和私有方法)
    在这里插入图片描述
  • 静态内部类(先认识一下,以后再讲)
    一旦加了static,这个 id 就拿不到了。因为先实例化了 Inner,那个时候 private id 还没有。除非把上面也改成 static 才可以。
    在这里插入图片描述
  • 一个java文件中只能有一个public class,但是可以有多个class文件。
  • 有时可以在这里写测试类,因为这里面可以写方法
    在这里插入图片描述
  • 类还可以写在方法里
    在这里插入图片描述
  • 匿名内部类
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

6.异常机制

(1)什么是异常

在这里插入图片描述

  • 例如:循环依赖
    在这里插入图片描述
  • 例如:被除数不能为0
    在这里插入图片描述
  • 简单分类
    在这里插入图片描述
(2)异常体系结构

在这里插入图片描述

  • 错误
    在这里插入图片描述
  • 异常
    在这里插入图片描述
(3)Java异常处理机制 &&(4)处理异常

在这里插入图片描述

  • finally 可以不要,一般 IO、资源等需要关闭的东西,可以用finally
  • try 和 catch 一般两个都有
    在这里插入图片描述
  • 未捕获到,但是finally仍然会输出,处理善后工作
    在这里插入图片描述
  • catch 里的参数就是想要捕获的异常类型
    在这里插入图片描述
  • 也可以捕获多个异常
  • 有个层层递进的关系,eg :Throwable 要写到最后面,不能写在最上面。不然的话后面就不会捕获了
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    因此,假设要捕获多个异常,需要从小到大!
  • 生成快捷键:选中代码语句,Ctrl + Alt + t ,会出现一些代码块自动帮你包裹起来,第7个就是 try/catch,第8个是 try/catch/finally,一般我们会选择 try/catch/finally
    在这里插入图片描述
  • 老师的和我不一样,自动生成打印错误的栈信息。也可以用自己的逻辑判断。例如如果出现异常,程序就结束,自己手动结束程序。
    在这里插入图片描述
    在这里插入图片描述
  • 主动抛出异常
    在这里插入图片描述
  • 输出没有什么变化,所以主动抛出异常一般在方法中使用,方法中 throw
    在这里插入图片描述
  • 方法上抛出异常(抛到更高阶)方法上 throws
    在这里插入图片描述
    如果不用 try/catch 的话,遇到错误程序就自动停止了。如果用 try/catch 捕获的话,程序还可以正常往下运行。即,如果错误在意料之中,可以让程序不停止。想办法让错误在 catch 中处理掉。
(5)自定义异常(用的不多)

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

总结

在这里插入图片描述

  • 快捷键:出现红色波浪线,按住 Alt + Enter,自动会提示怎么做
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值