面向对象(完结):常见关键字 + 补充

目录

关键字

this

super

this与super的区别

package和import

static

单例模式

饿汉式一

饿汉式二

懒汉式

​​​​​​​单例设计模式的应用场景

final

abstract

模板方法设计模式

interface

代理模式

接口和抽象类之间的对比

补充

可变个数形参的方法

Java的值传递机制★

形参

实参

形参是基本数据类型

形参是引用数据类型

包装类

==和equals的区别

垃圾回收机制


关键字

this

this可以调用类的属性、方法和构造器。

        在类的方法中

                可以使用"this.属性""this.方法"的方式,调用当前对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果方法的形参类的属性同名,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参

        this.name = name; //用this来区分属性局部变量

        在类的构造器中

                可以使用"this.属性""this.方法"的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果构造器的形参类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参

 ① 在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器。
 ② 构造器中不能通过"this(形参列表)"方式调用自己。
 ③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)"。
 ④ 规定:"this(形参列表)"必须声明在当前构造器的
首行
 ⑤ 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器。

 ⑥ 使用 this 访问属性和方法时,如果在本类中未找到,会从父类中查找。

class Person{
    String name;
    int age;
    int id;
  
  
    // 构造器内  形参和成员变量同名,必须使用this指明该变量是成员变量
    Person(String name ,int age){
        this.name = name;
        this.age = age;
    }


    // 方法内  形参与成员变量没有同名时,可使用this也可以省略
    public void getInfo(){
        System.out.println("姓名:" + name);
        this.speak();
    }


    public void speak(){
        System.out.println("年龄:" + this.age);
    }


    // 当前对象操作本方法时,用this指明
    public boolean compare(Person p){
        return this.name == p.name;
    }


    //this可以作为一个类中构造器的互相调用
    public Person(){    //无参构造器
        System.out.println("666");
    }
    public Person(String name){
        this();    //调用本类中的无参构造器
        this.name = name;
    }
    public Person(String name ,int age ,int id){
        this(name, age);    //调用两个参数的构造器
        this.id = id;
    }


}

super

super调用属性、方法:
        可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
        特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
        特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法


super调用构造器:
        可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器。
        "super(形参列表)"的使用,必须声明在子类构造器的首行
        在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二一,不能同时出现。
        在构造器的首行,没显式的声明"this(形参列表)"或"super(形参列表)"则默认调用的是父类中空参的构造器:super()
        在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器。
        如果子类构造器中既未显式调用父类或本类的构造器 且父类中又没有无参的构造器则编译出错。

class Person {
    protected String name = "666";
    protected int age;
    private Date birthDate;

    public Person(String name, int age, Date d){
        this.name = name;
        this.age = age;
        this.birthDate = d;
    }

    public Person(String name, int age){
        this(name, age, null);
    }
    
    public Person(String name, Date d){
        this(name, 18, null);
    }

    public Person(String name){
        this(name, 18);
    }

    public String getInfo() {
        return "Name: "+ name + "\nage: " + age;
    }
}

class Student extends Person {
    protected String name = "有点6";
    private String school = "哈佛";

    //super调用父类中的构造器
    public Student(String name, int age, String s){
        super(name, age);
        school = s;
    }

    public Student(String name, String s){
        super(name);
        school = s;
    }

    //编译出错:no super(),系统将调用父类中的无参构造器,但父类没有显式的声明无参构造器
    public Student(String s){
        school = s;
    }

    public String getSchool() {
        return school;
    }

    //调用的是父类的getInfo()
    public String getInfo() {
        return super.getInfo() + "\nschool: " + school;
    }

}

this与super的区别

package和import

package:包

         提供包的概念是为了更好的实现项目中类的管理,将功能相近的类划分到同一个包中,包可以包含类和子包划分项目层次便于管理,解决类命名冲突的问题,控制访问权限。
         
●​​​​​​​使用package声明类或接口所属的包,声明在源文件的首行。
         
​​​​​​​包属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”。
        
 每"."一次,就代表一层文件目录。

package 顶层包名.子包名;

 

import:导入
        ●在源文件中显式的使用import结构导入指定包下的类、接口。
        ●声明在包的声明和类的声明之间。
        ●如果需要导入多个结构,则并列写出即可。
        ●可以使用"xxx.*"的方式,表示可以导入xxx包下的所结构。
        ●如果使用的类或接口是java.lang包下定义的,则可以省略import结构。
        ●如果使用的类或接口是本包下定义的,则可以省略import结构。
        ●如果在源文件中,使用了不同包下的同名的类,则必须至少一个类需要以全类名的方式显示。
        ●使用"xxx.*"方式表明可以调用xxx包下的所结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入。
        ●import static:导入指定类或接口中的静态结构:属性或方法。 

import  包名 .类名;​​​​​​​

static

static 可用修饰属性 、 方法 、 代码块 、 内部类。

特点

        ●随着类的加载而加载。可以通过"类.静态变量"的方式进行调用。
        ●优先于对象存在。
        ●修饰的成员,被所有对象所共享。由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
        ●访问权限允许时,可不创建对象,直接被类调用。​​​​​​​

实例变量:

        创建了类的多个对象时,每个对象都独立的拥一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量(static):

        创建了类的多个对象时,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。

static修饰的方法称为:静态方法或类方法

        随着类的加载而加载,可以通过"类.静态方法"的方式进行调用。
        静态方法中,只能调用静态的方法或属性。
        非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

        静态方法中,不能使用this和super关键字

//静态方法中不能有this和super
class Person{
    private int id;
    public static int total = 0;

    public static int getTotal(){
        //注意静态方法内只能访问静态属性和方法,不能访问非静态的
        return total;
    }

    public Person(){
        total++;
        id = total;
    }

}

public class StaticTest{
    public static void main(String args[]){
        
        //不用创建对象就可以访问静态成员和静态方法
        Person.total = 100;
        sout(Person.getTotal());
    
        Person p = new Person();
        sout(p.total); //101


    }
}

单例模式

        单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。

饿汉式一:

class Bank{
	
	//1.私有化类的构造器
	private Bank(){
		
	}
	
	//2.内部创建类的对象,要求此对象也必须声明为静态的
	private static Bank instance = new Bank();
	
	//3.提供公共的静态的方法,返回类的对象
	public static Bank getInstance(){
		return instance;
	}

}

饿汉式二:

class Bank{
	
	//1.私化类的构造器
	private Bank(){
		
	}
	
	//2.声明当前类对象,没初始化,此对象也必须声明为static的
	private static Bank instance = null;

	static{
		instance = new Bank();
    }
	
	//3.声明public、static的返回当前类对象的方法
	public static Bank getInstance(){
		return instance;
	}
	
}

懒汉式:

class Bank{

    private Bank(){}

    private static Bank instance = null;

    public static Bank getInstance(){

        /**
        //方式一:效率稍差
        synchronized (Bank.class) {
            if(instance == null){

                instance = new Bank();
            }
           return instance;
        }
        */

        //方式二:效率更高
        if(instance == null){

            synchronized (Bank.class) {
                if(instance == null){

                    instance = new Bank();
                }

            }
        }
        return instance;
    }

}

饿汉式:    
        坏处:对象加载时间过长。
        好处:饿汉式是线程安全的。
  
懒汉式:

        好处:延迟对象的创建。

​​​​​​​单例设计模式的应用场景

        ●网站的计数器 ,一般也 是单例模式实现,否则难以同步。


        ●应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打状态,因为只能有一个实例去 操作, 否则内容不好追加。


        ●数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源 。


        项目中, 读取配置文件的类 ,一般也只有一个对象。没有必要每次使用配置文件数据 ,都生成一 个对象去读取 。


        ●Application 也是单例的典型应用。


        Windows 的 Task Manager ( 任务管理器 就是 很典型的单例模式。


        Windows 的 Recycle Bin 回收站 也 是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

final

可以用来修饰:类、方法、变量。

        final 用来修饰一个类:此类不能被其他类所继承。
                比如:String类、System类、StringBuffer类
        final 用来修饰方法:表明此方法不可以被重写。
                 比如:Object类中getClass();
        final 用来修饰变量:此时的"变量"就称为是一个常量。
        final修饰属性:可以考虑赋值的位置:显式初始化、代码块中初始化、构造器中初始化。
        final修饰局部变量:使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给 常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。 

        static final 用来修饰属性:全局常量。

public final int ID;
public Test() {
        ID = totalNumber ; 
// 可在构造器中给 final 修饰的“变量”赋值
}

abstract

可以用来修饰:类、方法。
abstract修饰类:抽象类
        > 此类不能实例化。
        > 抽象类中一定有构造器,便于子类实例化时调用。
        > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 --->抽象的使用前提:继承性

abstract修饰方法:抽象方法
        > 抽象方法只有方法的声明,没方法体。
        > 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的
        > 若子类重写了父类中的所有的抽象方法后,此子类方可实例化。
        > 若子类没重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰。

注意:

        abstract不能用来修饰:属性、代码块、构造器等结构。
        abstract不能用来修饰私方法、静态方法、final的方法、final的类。

模板方法设计模式

        抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。

abstract class Template{
	
	//计算某段代码执行所需要花费的时间
	public void spendTime(){
		
		long start = System.currentTimeMillis();
		
		this.code(); //不确定的部分、易变的部分
		
		long end = System.currentTimeMillis();
		
		System.out.println("花费的时间为:" + (end - start));
		
	}
	
	public abstract void code();
	
}

class SubTemplate extends Template{

	@Override
	public void code() {
		
		for(int i = 2;i <= 1000;i++){
			boolean isFlag = true;
			for(int j = 2;j <= Math.sqrt(i);j++){
				
				if(i % j == 0){
					isFlag = false;
					break;
				}
			}
			if(isFlag){
				System.out.println(i);
			}
		}

	}
	
}

//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {

	public static void main(String[] args) {

		BankTemplateMethod btmd = new DrawMoney();
		btmd.process();

		BankTemplateMethod btmm = new ManageMoney();
		btmm.process();

	}
}

abstract class BankTemplateMethod {
	// 具体方法
	public void takeNumber() {
		System.out.println("取号");
	}


	public abstract void transact(); // 办理具体的业务;钩子方法


	public void evaluate() {
		System.out.println("评分");
	}


	// 模板方法,把基本操作组合到一起,子类一般不能重写
	public final void process() {
		this.takeNumber();

		this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码

		this.evaluate();
	}
}


class DrawMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("取一个亿!!!");
	}
}

class ManageMoney extends BankTemplateMethod {
	public void transact() {
		System.out.println("我要存钱!");
	}
}

模板方法设计模式是编程中经常用得到的模式 。各个框架 、类库中都有他的影子比如常见的有:
        数据库访问的封装。
        Junit 单元测试。
        JavaWeb 的 Servlet 中关于 doGet/doPost 方法调用。
        Hibernate 中模板程序。
        Spring 中 JDBCTemlate 、 HibernateTemplate 等。

interface

接口 interface 是抽象方法和常量值定义的集合 。
接口的特点:
        用 interface 来定义 。接口和类是两个并列的结构
        接口中的所有成员变量都默认是由
public static final 修饰的 。
        接口中的所有抽象方法都默认是由
public abstract 修饰的 。
        接口中没有构造器,意味着接口不能实例化。
        接口与接口之间可以继承,而且可以多继承。

        Java类可以实现多个接口。

格式:class  AA  extends  BB  implements  CC, DD, EE{        //...        }

        接口的具体使用体现多态性。

        接口实际上可以看作是一种规范。

        JDK7及以前:只能定义全局常量和抽象方法。
                >全局常量:public static final修饰的,但是书写时,可以省略不写。
                >抽象方法:public abstract修饰的,可省略不写。
        JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。

 

//举例一:
interface Runner{

    public void start();
    public void run();

}

interface Swimmer{

    public double swim();

}

class Person {

    public void eat(){
        //...
    }
}

class Man extends Person implements Runner, Swimmer{
    
    public void start(){
        //...
    }

    public void run(){
        //...
    }

    public double swim(){
        //...
    }
}

public class Test{
    public static void main(String args[]){
        Test t = new Test();
        Man m = new Man();

        t.r(m);
        t.s(m);
        t.e(m);
    }

    public void r(Runner r){
        r.start();
        r.run();
    }
    
    public void s(Swimmer s){
        s.swim();
    }

    public void e(Person p){
        p.eat();
    }
}


//举例二:
interface MyInterface extends Runner{
    //...
}a

  

Java8中关于接口的新规范


        1:接口中定义的静态方法,只能通过接口来调用。

        2:通过实现类的对象,可以调用接口中的默认方法。如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法。

        3:如果子类(或实现类)继承的父类与接口中声明了同名同参数的默认方法,那么子类在没重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
        4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没重写此方法的情况下,报错。-->接口冲突。所以这就需要我们必须在实现类中重写此方法。

   5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法。

                

        public interface A{        default void method(){...}        }

        public interface B{        default void method(){...}        }

        class SupClass {        public void method(){...}        }

        class SubClass extends SubClass implements A, B{

                public void method(){...}

                

                public void myMethod(){

                        method(); //调用的是自己定义重写的方法

                        super.method();//调用的是父类中的

                        A.super.method(​​​​​​​);//A接口中的默认方法

                        B.super.method();//B接口中的默认方法

                }

}

代理模式

        代理模式是 Java 开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问。

应用场景:
        安全代理: 屏蔽对真实角色的直接访问 。
        远程代理: 通过代理类处理远程方法调用(RMI)。
        延迟加载: 先加载轻量级的代理对象 真正需要再加载真实对象。
比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时用 proxy 来进行大图片的打开 。


分类
        静态代理(静态定义代理类)
        动态代理(动态生成代理类)

interface Network {
    public void browse();
}


//被代理类
class RealServer implements Network{

    @Override
    public void browse() {
        System.out.println("真实服务器上网浏览信息");
    }
}

//代理类
class ProxyServer implements Network {
    private Network network;

    public ProxyServer(Network network ){
        this.network = network;
    }

    public void check() {
        System.out.println("检查网络连接等操作");
    }

    public void browse() {
        check();
        network.browse();
    }
}

public class ProxyDemo {
    public static void main(String[] args ){
        Network net = new ProxyServer(new RealServer());
        net.browse();
    }
}

public class StaticProxyTest {

	public static void main(String[] args) {

		Star s = new Proxy(new RealStar());
		s.confer();
		s.signContract();
		s.bookTicket();
		s.sing();
		s.collectMoney();
	}
}


interface Star {
	void confer();// 面谈

	void signContract();// 签合同

	void bookTicket();// 订票

	void sing();// 唱歌

	void collectMoney();// 收钱
}

class RealStar implements Star {

	public void confer() {
	}

	public void signContract() {
	}

	public void bookTicket() {
	}

	public void sing() {
		System.out.println("明星:歌唱~~~");
	}

	public void collectMoney() {
	}
}

class Proxy implements Star {
	private Star real;

	public Proxy(Star real) {
		this.real = real;
	}

	public void confer() {
		System.out.println("经纪人面谈");
	}

	public void signContract() {
		System.out.println("经纪人签合同");
	}

	public void bookTicket() {
		System.out.println("经纪人订票");
	}

	public void sing() {
		real.sing();
	}

	public void collectMoney() {
		System.out.println("经纪人收钱");
	}
}

接口和抽象类之间的对比

补充

可变个数形参的方法

 jdk 5.0新增了可变个数形参的方法。
具体使用:


    ●可变个数形参的格式:方法名(数据类型 ... 变量名)


        ●当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,...
        ●可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
        ●可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
        可变个数形参在方法的形参中,最多只能声明一个可变形参,且只能声明在最后。

        可变参数方法的使用与参数部分使用数组是一致的。

public void show(int i){ 
    System.out.println("int");
}

public void show(String s){
    System.out.println("String");
}

public void show(String ... s){ //与public void show(String[] s)效果一样
    //和数组一样
    for(int i = 0;i < s.length;i++){
        System.out.println(s[i]);
    }
    System.out.println("String ... s");
}


//调用
    test.show(666);
    test.show("老六了");
    test.show("奈斯","真的六啊","老铁666");
    test.show();
    test.show(new String[]{"A","N","B"});

Java的值传递机制★

Java里方法的参数传递方式只有一种:值传递 。将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

        形参:

                方法声明时的参数。

        实参:

                方法调用时实际传给形参的参数值。

        形参是基本数据类型:

                将实参基本数据类型变量的“数据值”传递给形参。

int  a  = 6;

System.out.println("修改前 a = " + a ); //6

change(a);

System.out.println("修改后 a = " + a); //6

public void change(int x){

        x = 3;

​​​​​​​}

        形参是引用数据类型:

                将实参引用数据类型变量的“地址值”传递给形参。

public static void main(String[] args){
    Person p = new Person();
    p.age = 8;

    System.out.println("修改前 age = " + p.age); //8
    change(p);
    System.out.println("修改后 age = " + p.age); //18
}

public static void change(Person o){
    o.age = 18;
}

class Person{
    int age;
}

        int[] a = new int[10];
        System.out.println(a); //输出地址值
        char[] c = new char[10];
        System.out.println(c);//不是地址值,如果里面有元素将输出元素
   

包装类

	//基本数据类型-->包装类:调用包装类的构造器
	@Test
	public void test1() {
		int num1 = 10;
		//System.out.println(num1.toString());
		Integer in1 = new Integer(num1);
		System.out.println(in1.toString());
		
		Integer in2 = new Integer("123");
		System.out.println(in2.toString());
	}
	

	//包装类-->基本数据类型
	@Test
	public void test2() {
		Integer in1 = new Integer(12);
		
		int i1 = in1.intValue();
		
		System.out.println(i1);
		
		
		Float f = new Float(122);
		System.out.println(f.floatValue() + 1);
	}
	

	/*
	 *  JDK 5.0新特性:自动装箱和拆箱
	 */
	@Test
	public void test3() {
	
		//自动装箱
		int num = 10;
		Integer n = num;
		
		
		boolean b = true;
		Boolean b1 = b;
		
		//自动拆箱:包装类->基本数据类型
		System.out.println(n.toString());
		int numb = n;//自动拆箱		
		
	}
	
	//基本数据类型、包装类 --> String类型:调用String重载的valueOf(Xxx xx)
	@Test
	public void test4() {
		int num1 = 11;
		//方式1:连接运算
		String str1 = num1 + "";
		
		//方式2:调用String的valueOf(Xxx xx)
		float f1 = 12.23f;
		String str2 = String.valueOf(f1);
		
		Double d = new Double(12.2);
		String str3 = String.valueOf(d);
		System.out.println(str2);
		System.out.println(str3);
	}

	// String类型--> 基本数据类型、包装类: 调用包装类的parseXxx()
	@Test
	public void test5() {
		String str1 = "123";
		System.out.println(Integer.parseInt(str1));
		
		
		String str2 = "true";
		boolean b1 = Boolean.parseBoolean(str2);
		
	}

==和equals的区别

        1、== 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型
就是比较内存地址。
        2、equals 的话,它是属于 java.lang.Object 类里面的方法,如果该方法没有被重写过默认也
是==,我们可以看到 String 等类的 equals 方法是被重写过的,而且 String 类在日常开发中
用的比较多,久而久之,形成了 equals 是比较值的错误观点。
        3、具体要看自定义类里有没有重写Object 的 equals 方法来判断。
        4、通常情况下,重写 equals 方法,会比较类中的相应属性是否都相等。

垃圾回收机制

        ●垃圾回收机制只回收JVM堆内存里的对象空间。
        ●对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力。
        ●现在的JVM有多种垃圾回收实现算法,表现各异。

        ●垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。

        ●可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。

        ●程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。
        ●垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一
个新的引用变量重新引用该对象,则会重新激活对象)。​​​​​​​
        ●永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

​​​​​​

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值