Java面向对象

面向对象

初识面向对象

  • 面向过程思想

    步骤清晰简单,第一步做什么,第二步做什么……(形似线性)

    面向过程适合处理一些较为简单的问题

  • 面向对象思想

    物以类聚,分类的思维模式,思考问题首先 会解决问题,需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。

  • 什么是面向对象

    • 面向对象编程(Object-Oriented Programming,简称 OOP)。

    • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

    • 面向对象是抽象的。

    • 三大特性

      • 封装
      • 继承
      • 多态
  • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题。

  • 对于描述复杂的事物,为了从宏观上把握、从整体上分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍需要面向过程的思路去处理。

方法回顾加深

方法的定义

  • 修饰符
  • 返回类型
  • break、return
  • 方法名:符合规范,见名知意
  • 参数列表:(参数类型 参数名)
  • 异常抛出

方法的调用

  • 静态方法

    • 调用静态方法可以直接使用 类名.方法名 去调用。

    • static方法不属于对象,是属于类,随着类的加载而加载

    • 在静态方法中,不可以直接调用非静态方法,要想调用,必须先实例化对象,然后再用 对象名.非静态方法 才可以。同理,在静态方法中,不可以直接调用非静态变量,可以先实例化对象,然后再用 对象名.非静态变量
      在这里插入图片描述

  • 非静态方法

​ 调用非静态方法需要先 实例化这个类(new) 然后 再通过 实例化变量.方法名 去调用。

  • 静态方法和非静态方法的代码举例

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

  • 形参和实参

在这里插入图片描述

  • **值传递和引用传递 **
    在这里插入图片描述
    在这里插入图片描述

  • this关键字

对象的创建分析

类与对象的关系

类是一种抽象的数据类型,它是对某一类事物整体的描述(这类事物应该具备的特点和行为),但是代表不了一个具体的事物。(动物类、植物类、学生类等)

对象是抽象概念的 具体实例。

创建和初始化对象

  • 使用new关键字创建对象

    使用new关键字创建的时候,除了 分配内存 空间以外,还会给创建好的对象 进行默认的初始化 以及对 类中构造器的调用

在这里插入图片描述

  • 类中的构造器

    类中的构造器也被称为 构造方法 ,是在进行创建对象的时候必须要调用的。并且具有以下两个特点。

    • 必须和类的名字相同

    • 必须没有返回类型,也不能写void

    • 代码演示

      package com.Hrstudy.oop.demo02;
      
      public class Application {
          public static void main(String[] args) {
              //new 实例化了一个对象
              Person person = new Person();
              System.out.println(person.name);    //huangran
      
          }
          /*
          * 构造器:
          *   1.和类名相同
          *   2.没有返回值
          * 作用:
          *   1.new 本质是在调用构造方法
          *   2.初始化对象的值
          * 注意点:
          *   1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
          * */
      }
      
      //Person类
      package com.Hrstudy.oop.demo02;
      
      public class Person {
          // 一个类即使什么都不写,它也会存在一个无参方法
          //显示的定义构造器
      
          String name;
      
          //实例化初始值
          //1. 使用new关键字,本质是在调用构造器
          public Person () {
              this.name = "huangran";
          }
      
          //有参构造:一旦定义了有参构造,就必须显示定义无参构造
          public Person(String name){
              this.name = name;
          }
      
          //快捷键:ALT + insert 可以调出创建构造器
      
      }
      
      
      • //快捷键:ALT + insert 可以调出创建构造器

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

创建对象的内存分析

代码:
在这里插入图片描述

画图分析:
在这里插入图片描述

类与对象的简单小结

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

  2. 方法

    定义、调用!

  3. 对象的引用

​ 引用类型:除了八种基本类型的其余类型

​ 对象是通过引用来操作的: 栈–>堆

  1. 类中的属性

    也称作字段名(Filed)、成员变量

    默认均有初始化:

    ​ 数字: 0 0.0

    ​ char: u0000

    ​ boolean: false

​ 引用: null

​ 创建属性均使用 属性类型 属性名 = 属性值!

  1. 对象的创建和使用
  • 必须使用 new 关键字创造对象,构造器 (构造方法) Person huangran = new Person( );

  • 对象的属性 huangran.name

  • 对象的方法 huangran.sleep( )

  1. 类:

​ 静态的属性 属性

​ 动态的行为 方法

面向对象的三大特性

封装

  1. 该露的露,该藏的藏

​ 我们程序设计要追求 “高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低 耦合就是仅暴露少量的方法给外部使用。

  1. 封装也就是数据的隐藏

​ 通常,应该禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这成为信息隐藏。

  1. 属性私有,get/set

  2. 代码演示

    主方法:

    package com.Hrstudy.oop.demo03;
    
    
    public class Application {
        public static void main(String[] args) {
            //new 实例化了一个对象
            Student s1 = new Student();
            s1.setName("美女");
            System.out.println(s1.getName());
    
            s1.setAge(1111);
            System.out.println(s1.getAge());
        }
    }
    

​ Student类:

package com.Hrstudy.oop.demo03;

//类 private:私有
public class Student {
    //属性私有
    private String name;//名字
    private int id;     //学号
    private char sex;   //性别
    private int age;    //年龄
    //提供一些可以操作这个属性的方法!
    //get  获取这个数据
    public String getName(){
        return this.name;
    }
    //set  给这个数据设置值
    public void setName(String name){
        this.name = name;
    }

    //Alt + Insert 快捷键创建get/set方法

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age > 120 || age < 0){ //通过set方法可以在程序内部保证数据准确性
            this.age = 3;
        }else{
            this.age = age;
        }
    }

    /*
       封装特性:
       1. 提高程序的安全性,保护数据
       2. 隐藏代码的实现细节
       3. 统一接口
       4. 系统的可维护增加了
    */
}
  • //Alt + Insert 快捷键创建get/set方法图示
    在这里插入图片描述
    在这里插入图片描述

继承

继承和类的关系
  • 继承类和类之间的一种关系,除此之外,类和类之间关系还有依赖、组合、聚合等。

  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends

  • Java类中只有单继承,没有多继承。(意思是,一个儿子只能有一个亲爸爸,但一个爸爸可以有多个儿子)

  • 在Java中,所有的类,都默认直接或者间接继承Object。

代码演示

在这里插入图片描述

  • 快捷键展现 类的族谱(Ctrl + H)
    在这里插入图片描述
super 关键字
  • 子类使用 super 操作父类的属性

在这里插入图片描述

  • 子类使用 super 操作父类的方法

在这里插入图片描述

子类的无参构造方法默认使用super调用的父类的无参构造
在这里插入图片描述

  • 私有方法的无法被继承
super注意点
  • super调用父类的构造方法,必须写在子类构造方法的第一行

  • super只能出现在子类的方法或者子类的构造方法中

  • super 和 this 不可以同时调用构造方法!

  • 父类出现有参构造前提下,如果子类需要创造无参构造,父类中必须显示声明无参构造,否则会报错!

  • super 和 this 不同点

    • 代表的对象不同

      this : 本身调用者的这个对象

      super :代表父类的对象的引用

    • 前提条件不同

      this :没有继承也可以使用

      super : 只能在继承的条件下使用

    • 构造方法含义不同

      this() : 本类的构造

      super(): 父类的构造

方法重写
  • 方法重写需要有继承关系子类重写父类的方法

  • 方法名必须相同,参数列表必须相同(快捷键 alt+insert --> override)

  • 被重写的方法修饰符,范围可以扩大,不可以缩小。 pubic>protected>default>private

  • 方法重写后抛出的异常,范围可以缩小,不可以扩大! ClassNotFoundException --> Exception(大)

  • 方法重写是为了满足 父类未提供给子类的功能 。

  • 代码演示

    • 父类和子类都是静态方法

在这里插入图片描述

静态方法: ​ 实例化,静态方法的调用只和左边定义的数据类型有关。静态的方法和非静态的放法区别很大,不要随意使用静态方法。
  • 父类和子类非静态方法

在这里插入图片描述

父类的引用指向了子类

​ 如果被调用方法,在子类和父类中均存在,最终执行的被调用方法,取决于子类对象中是否存在被调方法的重写,若存在,则最终执行的是子类中的,否则,是父类中的。(子类中有调用子类)。

多态

多态相关知识点
  • 多态实现了动态编译(可扩展性增强)。
  • 即同一个方法可以根据发送对象的不同采用多种不同的行为方式。(根据下面的代码体验)
  • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。(父类、有关系的)
  • 多态是方法的多态,和方法重写一样,属性也不具有多态性。
  • 多态存在的条件
    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
代码图示

在这里插入图片描述

多态使用注意点
  • 多态是方法的多态,属性没有多态。

  • 父类和子类,有联系,会有一种类型转化异常。 ClassCastException!

  • 多态使用的条件:有继承关系、方法需要重写、父类引用指向子类对象!( Father f1 = new Son(); )

  • 不能使用多态的情况

    • static 方法 ,是属于类的,不属于实例。

    • final 常量。

    • private 方法。

instanceof关键字

  • 是用来判断类与类之间的关系,如果存在父子类关系,返回true;不是父子类关系,返回false;毫无关系,则编译报错。

  • 代码图示及演示
    在这里插入图片描述

package com.Hrstudy.oop.demo07;

public class Application {
    public static void main(String[] args) {
        //测试 instanceof

        //线路有三条
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object Object = new Student();

        System.out.println(Object instanceof Student);//true
        System.out.println(Object instanceof Person);//true
        System.out.println(Object instanceof Object);//true
        System.out.println(Object instanceof Teacher);//false
        System.out.println(Object instanceof String);//false
        System.out.println("=============================");

        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        //System.out.println(person instanceof String);//编译报错 Person 和 String 毫无瓜葛
        System.out.println("=============================");

        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        //System.out.println(student instanceof Teacher);//编译报错
        //System.out.println(student instanceof String);//编译报错
        System.out.println("=============================");
    }
}
父类与子类之间类型转换(主要讲解父类与子类的强制转换)
  • 代码图示及演示
    在这里插入图片描述
package com.Hrstudy.oop.demo08;

public class Application {
    public static void main(String[] args) {
        //父类和子类之间类型的转换

        //子类转父类     低 --> 高   自动转换
        Person s1 = new Student();

        s1.run(); //可以使用从父类继承的方法
        //s1.go(); //不可以使用子类中自己的方法,级别太高,需要向下转型(强制转换)

        //为了使用子类中自己的方法,需要将 s1 这个对象类型由Person类型转换为Student类型!
        Student s2 = (Student) s1;
        s2.run();   //可以使用从父类继承的方法
        s2.go();    //可以使用子类中自己的方法

        //上面的强制转换可以简写为
        ((Student) s1).go(); //将s1强制转换后,调用子类自身的 go 方法
    }
}
  • 父类与子类之间类型转换小结
    1. 父类引用指向子类的对象 Father f1 = new Son ( );
    2. 把子类转换为父类,为向上转型
    3. 把父类转换为子类,为向下转型,需要强制转换
    4. 引用数据类型进行强制转换时,子类可能会丢失一些自己的方法,普通类型(int,float等)进行强制转换也可能会丢失数据的精度。
    5. 进行强制转换是为了方便方法的调用,减少重复的代码,更加简洁。

static关键字总结

代码案例

  • 静态变量使用

    • 静态变量通过 类名.静态变量名 即可使用。
    • 非静态变量需要实例化一个对象之后 通过 对象名.非静态变量名 使用。
    • 静态变量也可以通过非静态变量的方式使用。
    package com.Hrstudy.oop.demo09;
    
    public class Student {
        //静态变量  多线程使用较多
        private static int age;
        //非静态变量
        private int score;
    
        public static void main(String[] args) {
            Student s1 = new Student();
            System.out.println(Student.age); //静态变量通过 类名.静态变量名 即可使用
            //System.out.println(Student.score); //非静态变量不可以这么使用,会报错
            System.out.println("=======================");
            System.out.println(s1.score);  //非静态变量需要实例化一个对象之后 通过 对象名.非静态变量名 使用
            System.out.println(s1.age); //静态变量也可以通过非静态方法使用
        }
    }
    
  • 静态方法使用

    • 静态方法可以通过 类名.静态方法名 使用。
    • 静态方法也可以直接调用,主方法中直接使用 静态方法名
    • 非静态方法需要先实例化,再用 对象名.非静态变量名 使用。
    • 静态方法也可以通过非静态方法的方式使用。
    package com.Hrstudy.oop.demo09;
    
    public class Teacher {
        //非静态方法
        public void run(){
            System.out.println("非静态方法");
        }
    
        //静态方法
        public static void go(){
            System.out.println("静态方法");
        }
    
        public static void main(String[] args) {
            go(); //静态方法可以直接调用
            Teacher.go(); //静态方法可以通过 类名.静态方法名 使用
    
            Teacher teacher = new Teacher();
            teacher.run(); //非静态方法需要先实例化 在调用
        }
    
    }
    
  • 静态代码块

    • 静态代码块是所有代码块最先执行的,随着类的加载而加载。
    • 静态代码块一般用来赋初始值
    • 静态代码块只随类的加载只执行一次
    package com.Hrstudy.oop.demo09;
    
    public class CodeBlack {
        //代码块讲解
    
        //1.匿名代码块  (程序中用来赋 初始值 的)
        {
            System.out.println(&quot;匿名代码块&quot;);
        }
    
        //2.静态代码块
        static {
            System.out.println(&quot;静态代码块&quot;);
        }
    
        //3.构造方法
        public CodeBlack(){
            System.out.println(&quot;构造方法&quot;);
        }
    
        public static void main(String[] args) {
            CodeBlack c1 = new CodeBlack(); //第一次运行输出 静态代码块   匿名代码块   构造方法
            System.out.println(&quot;===================================&quot;);
            CodeBlack c2 = new CodeBlack(); //第二次执行输出 匿名代码块   构造方法
    
            //静态代码块只随类的加载执行一次
    
        }
    }
    
  • 静态导入包

    • 静态导入包可以具体到包中的哪一个方法。
    • 声明了静态导入包后,在主方法中,可以直接使用方法名来调用该方法
    package com.Hrstudy.oop.demo09;
    
    //静态导入包
    import static java.lang.Math.random; //具体到方法名
    import static java.lang.Math.PI;
    
    public class StaticPackage {
        public static void main(String[] args) {
            //静态导入包
    
            //例如调用数学函数的随机数
            //正常方法
            double a = Math.random();
            System.out.println(a);
    
            //静态导入包的方法
            System.out.println(random()); //直接使用方法名,输出随机数
            System.out.println(PI); //直接输出圆周率
    
        }
    }
    

抽象类和接口

抽象类

  • 抽象类就是用abstract修饰的类;同理,抽象方法就是用abstract修饰的方法
  • 不能去 new 这个抽象类,只能靠子类去实现它,形成约束!
  • 抽象类中可以写普通的方法,但是,抽象方法只能写在抽象类中
  • 继承了抽象类的子类,需要实现父类中所有抽象方法除非子类也是抽象类

在这里插入图片描述

接口

  • 接口就是规范(专业的约束),在接口中无法写方法约束和实现是分离的(大多数程序都是面向接口编程)。

  • 接口的本质是契约,就像我们人间的法律一样,制定好后大家一起遵守。

  • 接口与实现接口的规则

    • 定义接口的关键词是 interface
    • 在接口中定义的方法都是抽象的,默认修饰词都是 public abstract;在接口中定义的属性,默认修饰词都是 public static final,被视为常量(需要大写属性名)。
    • 接口中定义的方法不能被实例化(和抽象类一样),接口中没有构造方法,无法new。
    • 实现接口类的关键词是 implements,接口可以实现多继承(java类只有单继承)。
    • 实现接口类必须要重写接口中的方法
  • 接口代码图示

在这里插入图片描述

内部类

定义

  • 内部类就是一个在类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就称之为内部类,而A类相对B类来说就是外部类了。

    //相对于内部类的外部类

    public class People{
    //内部类
    public class love{

    ​ }

    }

  • 内部类的注意点

    内部类可以访问到外部类的静态成员,但是不能访问外部类的实例成员,因为实例成员是由对象创建的,内部类无法找到,除非在内部类中new一个对象,进行间接的访问。

  • 内部类的使用场景

    (1)当一个事物的内部,还有一部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计。

    (2)内部类通常可以方便访问外部类成员,包括私有的成员。

    (3)内部类提供了更好的封装性,内部类本身可以用private、protected等修饰,封装性可以做更多的控制。

分类

成员内部类(静态,非静态)
  • 1.成员内部类

    • 成员内部类是定义在外部类的成员位置,并且没有static的修饰。

    • **成员内部类可以直接访问外部类的所有成员,包括私有权限的。**因为,内部类的实例对象是在外部类创建之后而创建的。

    • 成员内部类可以添加任意访问修饰符,因为它的地位就是一个成员。

      //外部类
      public class outer{
          //成员内部类
          public class inner{
          }
      }
      
    • 成员内部类的作用

      (1)作为外部类的成员

      • 可以调用外部类的结构。
      • 可以被static修饰。
      • 可以被四种不同的权限修饰。

      (2)作为一个类

      • 类中可以定义属性、方法、构造器等。
      • 可以被final修饰,表示此类不能被继承;不使用final,就可以被继承。
      • 可以被abstract修饰。
    • 成员内部类创建对象的格式:

      外部类名.内部类名 对象名 = new 外部构造器.new内部构造器( );

      outer.inner in = new outer().new inner();

  • 2.静态内部类(有static修饰)

    • 静态内部类中可以定义静态成员和实例成员。外部类以外的其他类需要通过完整的 类名.静态内部类名.静态变量名 来访问。

      public class Outer {
          //静态内部类
          static class Inner {
              int a = 0;    // 实例变量a
              static int b = 0;    // 静态变量 b
          }
      }
      //其他类
      class OtherClass {
          Outer.Inner oi = new Outer.Inner();
          int a2 = oi.a;    // 访问实例成员
          int b2 = Outer.Inner.b;    // 访问静态成员
      

    }

    
    * 静态内部类可以直接访问外部类的静态成员,**如果访问外部类的实例成员,则需要通过外部类的实例去访问。**
    
    ```java
    public class Outer {
        int a = 0;    // 实例变量
        static int b = 0;    // 静态变量
        static class Inner {
            Outer o = new Outer;
            int a2 = o.a;    // 访问实例变量
            int b2 = b;    // 访问静态变量
        }
    }
    
    • 静态内部类创建对象的格式:

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

      outer.inner in = new outer.inner();

局部内部类(方法内,代码块内,构造器内)
  • 局部内部类是放在方法、代码块、构造器等执行体中。
//外部类
public class Test {
    //当前方法
    public void method() {
        // 局部内部类
        class Inner {
   
        }
    }
}
  • 局部内部类和局部变量一样,不能使用访问控制修饰符

  • 局部内部类中不能定义static成员

  • 局部内部类中可以访问外部类的所有成员

  • 局部内部类中只可以访问 当前方法中 final 类型 的参数与变量。如果当前方法中的成员与外部类中的成员同名,则可以使用 外部类类名.this.成员名

匿名内部类
  • 匿名内部类实际上是一个没有名字的局部内部类,定义在当法中、代码块中、等。方便创建子类对象,最终目的为了简化代码编写

  • 使用匿名对象来调用,但是匿名对象没有引用变量,每次创建一个匿名对象都在堆中创建内存,都具有不同的内存地址,这样比较浪费资源

  • 格式:

    People p = new People(){
        public void run(){
        }
    };
    p.run();
    
    new 类名|抽象类名|或者接口名(){
            重写方法;
    };
    
    
  • 体验使用匿名内部类的对比:

    //之前学习多态的方法,在子类中重写父类的方法。
    public static void main(String[] args) {
    //父类       
                class People{
                void run() {
     
                }
            }
    //子类
            class Student extends People{
     
                @Override
                public void run() {
                    System.out.println("小学生跑的慢");
                }
            }
     
            People p = new Student();
             p.run();
        }
    //输出结果:
    //小学生跑的慢
    
    //使用了匿名内部类简化了代码的写法
    public static void main(String[] args) {
            class People{
                void run() {
     
                }
            }
    //匿名内部类
            People p = new People(){
                void run(){
                    System.out.println("小学生跑的慢");
                }
            };
             p.run();
        }
    //输出结果:
    //小学生跑的慢
    

代码演示

package com.Hrstudy.oop.demo12;
//一个java类中可以有多个class类,但是只能有一个 public class
public class Outer {
    private int id = 10;
    public void out(){
        System.out.println("这是外部类的方法");
    }

    //1.成员内部类
    public class Inner{
        public void in(){
            System.out.println("这是成员内部类的方法");
        }

        //获取外部类的私有属性
        public void getID() {
            System.out.println(id);
        }
    }
    //2.静态内部类
     static class Inners{
        public void in(){
            System.out.println("这是静态内部类的方法");
        }
    }

    //3.局部内部类
    //可以在局部内部类中new 一个对象来调用
    public void method(){
        class Inner{
            public void in(){
                System.out.println("这是局部内部类的方法");
            }
        }
        Inner in = new Inner();
        in.in();
    }



}
//一个java类中可以有多个class类,但是只能有一个 public class
class one {

}

//main方法

package com.Hrstudy.oop.demo12;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        //成员内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();         //这是成员内部类的方法
        inner.getID();      //10

        //静态内部类
        Outer.Inners inners = new Outer.Inners();
        inners.in();        //这是静态内部类的方法

        //局部内部类
        outer.method();     //这是局部内部类的方法
    }
}

//匿名内部类演示

package com.Hrstudy.oop.demo12;

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存到变量中
        //匿名对象
        new Apple().eat();
        UserService userService = new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}

class Apple{
    public void eat(){
        System.out.println("1");
    }
}
//创建接口
interface UserService{
    void hello();
}
lass
class one {

}

//main方法

package com.Hrstudy.oop.demo12;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        //成员内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();         //这是成员内部类的方法
        inner.getID();      //10

        //静态内部类
        Outer.Inners inners = new Outer.Inners();
        inners.in();        //这是静态内部类的方法

        //局部内部类
        outer.method();     //这是局部内部类的方法
    }
}

//匿名内部类演示

package com.Hrstudy.oop.demo12;

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存到变量中
        //匿名对象
        new Apple().eat();
        UserService userService = new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}

class Apple{
    public void eat(){
        System.out.println("1");
    }
}
//创建接口
interface UserService{
    void hello();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值