(六)java面向对象编程(中级)

十八.面向对象编程(中级)

在这里插入图片描述

IDE快捷键(修改过的)
操作快捷键
删除当前行Ctrl + D
复制当前行Ctrl + Alt + 下
注释Ctrl + /
格式化代码Ctrl + shift + L
设置Ctrl + Alt + S
生成构造器Alt + Insert
查看类的层级关系Ctrl + H
定位到这个类的方法Ctrl + B

​ 包的三大作用:

  • 区分相同名字的类
  • 当类很多时,可以更好的管理类 [ 看API文档 ]
  • 控制访问范围
package com.use;

import com.xiaoming.Dog;

public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        System.out.println(dog1);

        com.xiaoqiang.Dog dog2 = new com.xiaoqiang.Dog();
        System.out.println(dog2);
    }
}

包的规则:

  • 只能包含数字字母,下划线,小圆点,但是不能用数字开头,不能是关键字或者保留字
  • 一般是小写字母+小圆点
  • com.公司名.项目名.业务模块

java中常用的包

  • java.lang.*//基本包,默认引入,不需要再引入
  • java.util.*//util包,系统提供的工具包,工具类,使用Scanner
  • java.net.*//网络包,网络开发
  • java.awt.*//java的界面开发,GUI

​ 建议导入包的时候需要哪个导入哪个,不要直接导入*

​ 一个类中最多只有一个package

访问修饰符

​ java提供了四种访问修饰符

  • 公开级别:public公开类
  • 受保护级别:protected保护类
  • 默认级别:没有修饰符,向同一个包的公开类
  • 私有类别:peivate修饰,只有类本身可以访问,其余的不能访问。
访问级别访问修饰符同类同包子类不同包
公开publictruetruetruetrue
受保护protectedtruetruetruefalse
默认没有修饰符truetruefalsefalse
私有privatetruefalsefalsefalse

使用的注意事项:

  • 修饰符可以用来修饰类中的属性,成员方法以及类
  • 只有默认的和public才能修饰类,并且遵循上述访问权限的特点
  • 成员方法的访问规则和属性完全一样。
封装

​ 封装就是把抽象的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(方法),才能对数据进行操作。

​ 封装的好处:

  • 可以隐藏实现的细节:方法(连接数据库)< – 调用(传入参数)
  • 可以对数据进行验证,保证安全合理

​ 封装的实现

  • 将属性进行私有化(不能直接修改属性)
  • 提供一个公共的(public)set方法,用于对属性判断并赋值
  • 提供一个公共的(public)get方法,用于获取属性的值

idea快捷键:alt + insert 然后就setter and getter

继承

继承的基本语法

class 子类 extens 父类{

}

  • 子类会自动拥有父类定义的属性和方法
  • 父类又叫做超类,基类
  • 子类又叫做派生类

最主要的是能够解决代码的冗余问题

​ 子类继承了所有的属性和方法,但是私有属性和方法不能在子类直接访问,要通过访问公共的方法去访问。

​ 子类必须调用父类的构造器,完成父类的初始化,父类先被调用,子类后被调用。

​ 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,必须在子类的构造器中用super去指定父类的哪个构造器完成对父类的初始化工作,否则编译不会通过。

package com.use.encap.improve;

public class improve01 extends improve{
    public improve01() {
        //super();//默认使用了super
        super("jack",123);
        //this();//这里不能使用this();
        System.out.println("improve01");
    }
    public improve01(String name, int age){
        super("Tom",13);
        System.out.println("父类被调用");
    }

    public void say01(){
        System.out.println(n1 + n2 + n3 );//n4因为是私有的,所以不能访问。
    }

    public static void main(String[] args) {
        improve01 aaa = new improve01();
        aaa.say01();
    }

}
package com.use.encap.improve;

public class improve {
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    public improve(String name ,int age) {//无参构造器
        System.out.println("improve");
    }

    public void test001(){
        System.out.println("100");
    }

    protected void test002(){
        System.out.println("200");
    }

    void test003(){
        System.out.println("300");
    }

    private void test004(){
        System.out.println("400");
    }
}

​ 如果希望指定去调用父类的某个构造器,则显示的调用一下:super(参数列表)

​ super在使用时,需要放在构造器的第一行

​ super()和this()都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器。

​ java中所有类都是Object类的子类,Object是所有类的基类。

​ 父类构造器的调用不限于直接父类,将一致往上追溯到Object(顶级父类)

​ 子类最多只能继承一个父类(直接继承),java中是单继承机制。

​ 不能滥用继承,子类和父类之间必须满足is - a的逻辑关系。

​ Person is a Music?

package com.use.encap.homework01;

public class homework01 {
    //编写类,其中包含CPU,内存,硬盘等属性,getDetails方法用于返回类的详细信息
    //编写PC子类,继承该类,添加特有属性品牌brand
    //编写Notepad子类,继承该类,添加特有属性颜色color
    //编写Test类,在main方法中创建PC和Notepad对象,分别给对象中特有的属性赋值,以及对该类继承的属性赋值,并使用方法打印输出信息。
    private String CPU;
    private int memory;
    private int disk;

    public homework01(String CPU,int memory,int disk){
        this.CPU = CPU;
        this.memory = memory;
        this.disk = disk;
    }

    public String getCPU() {
        return CPU;
    }

    public void setCPU(String CPU) {
        this.CPU = CPU;
    }

    public int getMemory() {
        return memory;
    }

    public void setMemory(int memory) {
        this.memory = memory;
    }

    public int getDisk() {
        return disk;
    }

    public void setDisk(int disk) {
        this.disk = disk;
    }

    public String Details(){
        return "CPU:" + CPU + " " + "memory:" + memory + " " + "disk:" + disk + " ";
    }
}
package com.use.encap.homework01;

import java.sql.SQLOutput;

public class Notepad extends homework01{
    private String color;
    public Notepad(String CPU, int memory, int disk,String color) {
        super(CPU, memory, disk);
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public void pinfo(){
        System.out.println("输出的结果为:" + Details() + "color:" + color);
    }
}
package com.use.encap.homework01;

public class PC extends homework01 {

    private String brand;

    public PC(String CPU, int memory, int disk, String brand) {
        super(CPU, memory, disk);
        this.brand = brand;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void pinfo(){
        System.out.println("输出的结果为:" + Details() + "brand:" + brand);
    }

}
package com.use.encap.homework01;

public class main {
    public static void main(String[] args) {
        Notepad aaa = new Notepad("intel",32,500,"bule");
        PC bbb = new PC("intel",32,600,"华为");
        aaa.pinfo();
        bbb.pinfo();
    }
}
Super关键字

​ super代表父类的引用,用于访问父类的属性,方法,构造器。

​ 可以访问父类的属性,但是不能访问父类的private属性

​ 可以访问父类的方法,但是不能访问父类的peivate方法

​ 访问父类的构造器:只能放在构造器的第一句,只能出现一句话。

​ 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)

​ 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须访问super。如果没有重名,通过super访问是一样的效果。

​ super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以是使用super去访问爷爷类的成员,如果多个基类中都有同名的成员,使用super访问遵循就近原则。如果父类中没有该成员名,则继续在爷爷类中进行寻找。当然也是要遵循访问权限的原则。

区别thissuper
访问属性访问本类中的属性,如果本类中没有此属性,则从父类中继续查找从父类开始查找属性
调用方法访问本类中的方法,如果本类没有此方法咋从父类中继续查找从父类开始查找方法
调用构造器调用本类构造器,必须放在构造器的首行调用父类构造器,必须放在子类构造器的首行
特殊表示当前对象子类中访问父类对象
方法重写/(覆盖)

​ 就是说子类中有一个方法,和父类的某个方法的名称,返回类型,参数一致,就说这个子类的方法覆盖了父类的方法。

​ 方法重写的细节:

  • 子类的方法的参数名称,方法名称要和父类方法的参数,方法名称完全一致
  • 子类方法的返回类型和父类方法的返回类型一致,或者父类返回类型的子类
  • 子类方法不能缩小父类方法的访问权限
名称发生范围方法名参数列表返回类型修饰符
重载(overload)本类必须一样类型,个数,或者顺序至少有一个不同无需求无要求
重写(override)父子类必须一样相同子类重写的方法,返回的类型和父类返回的类型是一致的,或者说是其子类子类方法不能缩小父类方法的范围
package com.use.encap.homework02;

public class Person {
    //编写一个Person类,包括属性/private(name,age),构造器,方法say(返回自我介绍的字符串)
    //编写一个Student类,继承Person类,增加id,score属性/private,以及构造器,定义say方法(返回自我介绍的信息)
    //在main中,分别创建Person和Student对象,调用say方法输出自我介绍。
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say(){
        return "name:" + name + " " + " age:" + age + " ";
    }
}
package com.use.encap.homework02;

public class Student extends Person{
    private int id;
    private double score;

    public Student(String name, int age,int id,double score) {
        super(name, age);//调用父类构造器
        this.id = id;
        this.score = score;
    }

    public String say(){
        return super.say() + "id:" + id + "  " + "score:" + score + " ";
    }

    public int getId() {
        return id;
    }

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}
package com.use.encap.homework02;

public class main {
    public static void main(String[] args) {
        Person aaa = new Person("Tom",13);
        Student bbb = new Student("jack",14,5,37);
        System.out.println(aaa.say());
        System.out.println(bbb.say());
    }
}
多态

​ 可以提高代码的复用性,方便代码的维护,建立在封装和继承的基础之上的。

​ 对象的多态

  • 一个对象的编译里欸选哪个和运行
  • 编译类型在定义对象时,就确定了,不能改变
  • 运行类型是可以改变的
  • 编译类型要看等号的左边,运行类型要看等号的右边

​ 父类的引用指向子类的对象

​ 在编译阶段,能调用那些成员,是由编译类型决定的。

​ 可以调用父类的所有成员,但是不能调用子类的特有成员

Animal animal = new Cat();
Cat cat = (Cat) animal;

​ 属性没有重写这一个说,属性的值看编译类型

​ 属性看编译,方法看运行

java的动态绑定机制
  • 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定(和运行类型绑定,执行改方法的时候,首先找到该方法的运行类型,看看是否能够找到,若找不到就到父类进行寻找。)
  • 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用。
java动态数组
package com.use.encap.pro02;

public class Person {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public String say(){
        return name + "\t" + age + "\t";
    }
}
package com.use.encap.pro02;

public class student extends Person{
    private double score;

    public student(String name, int age,double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public String say() {
        return super.say() + "score=" + score;
    }

    public void study(){
        System.out.println("学生:" + getName());
    }
}
package com.use.encap.pro02;

public class teacher extends Person{
    private double salary;

    public teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String say() {
        return super.say() + "salary=" + salary;
    }

    public void teacher(){
        System.out.println("老师:" + getName());
    }
}
package com.use.encap.pro02;

public class main {
    public static void main(String[] args) {
        Person[] persons = new Person[5];
        persons[0] = new Person("jack",14);
        persons[1] = new student("name01",15,17.00);
        persons[2] = new teacher("name02",17,97.00);
        persons[3] = new teacher("name02",17,97.00);
        persons[4] = new teacher("name02",17,97.00);

        for (int i = 0; i < persons.length; i++){
            System.out.println(persons[i].say());
            
            if (persons[i] instanceof student){
                student student = (student)persons[i];
                student.study();
            } else if (persons[i] instanceof teacher) {
                teacher teacher = (teacher)persons[i];
                teacher.teacher();
            }else {
                System.out.println("您的类型有误,请检察");
            }
        }
    }
}
package com.use.encap.pr03;

public class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getAnnual(){
        return 12 * salary;
    }
}
package com.use.encap.pr03;

public class Manager extends Employee{

    private double bonus;

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public void manage(){
        System.out.println("经理:" + getName() + " is managing");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}
package com.use.encap.pr03;

public class worker extends Employee{

    public worker(String name, double salary) {
        super(name, salary);
    }

    public void work(){
        System.out.println("普通员工:" + getName() + " is working");
    }

    @Override
    public double getAnnual() {//因为普通的员工没有奖金,所以直接调用就好
        return super.getAnnual();
    }
}
package com.use.encap.pr03;

import javafx.concurrent.Worker;

public class Test {

    public void showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }

    public void testwork(Employee e) {
        if (e instanceof worker) {
            ((worker) e).work();//向下转型操作
        } else if (e instanceof Manager) {
            ((Manager) e).manage();//向下转型操作
        } else {
            System.out.println("不做处理!!!");
        }
    }

    public static void main(String[] args) {
        worker Tom = new worker("Tom", 13577);
        Manager Jack = new Manager("Jack", 23445, 1466);
        Test test = new Test();
        test.showEmpAnnual(Tom);
        test.showEmpAnnual(Jack);

        test.testwork(Tom);
        test.testwork(Jack);
    }
}
Object类详解
equals和==的对比
  • ==既可以判断基本类型,又可以判断引用类型。
  • ==如果判断基本类型,判断的是数值是否相等。
  • ==如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象。
  • equals只能判断引用类型,equals指的是值是否相等。
  • equals在比较String,Date,ArratList等类的时候,进行了方法的重写,不是进行比较地址,而是进行比较两者的内容是否相等。
Hash_Code
  • 提高具有哈希结构的容器的效率。
  • 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的。
  • 两个引用,如果指向的是不同对象,则哈希值是不一样的。
  • 哈希值主要根据地址号来的,不能完全将哈希值等价于地址。
  • 在集合中,如果hash需要的话,也会进行重写。
to_String
  • 默认返回:全类名 + @ + 哈希值的十六进制
  • 重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式。
  • 当直接输入一个对象时,toString方法会被默认的调用。(System.out.println(object))
finalize

(平常几乎不会用)

  • 当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该类方法,做一些释放资源的操作
  • 什么时候被回收:当某个对象没有任何引用时,则JVM就会认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象之前,会先调用finalize方法。
  • 垃圾回收机制的调用,是由系统来决定的(有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制。

如果不重写finalize,默认调用object中的finalize

调用垃圾回收方法并会不会造成阻塞。

断点调试

练习
//1.定义一个Person类{name,age,job},初始化Person对象数组,有3个person,并按照age从大到小进行排序,使用冒泡排序。
package com.use.encap.homework03;

import com.use.encap.pro02.Person;

class person {
    private String name;
    private int age;
    private String job;

    public person(String name, int age, String job) {
        this.name = name;
        this.age = age;
        this.job = job;
    }

    @Override       //这里重写了toString方法下面输出的结果才不是类名
    public String toString() {
        return "person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

public class homework {
    public static void main(String[] args) {
        person[] pp = new person[3];
        pp[0] = new person("jack", 13, "good");
        pp[1] = new person("rose", 15, "nice");
        pp[2] = new person("mack", 50, "bad");

        for (int i = 0; i < pp.length; i++) {
            System.out.println(pp[i]);  //输出的是默认对象的toString()
        }

        person bb = null;
        for (int i = 0; i < pp.length - 1; i++) {
            for (int j = i; j < pp.length - 1 - i; j++) {
                if (pp[i].getAge() < pp[i + 1].getAge()) {
                    bb = pp[i];
                    pp[i] = pp[i + 1];
                    pp[i + 1] = pp[i];
                }
            }
        }

        System.out.println("=========================");
        System.out.println("排序之后的结果如下:");
        for (int i = 0; i < pp.length; i++) {
            System.out.println(pp[i]); //输出的是默认对象的toString()
        }

    }
}
 //2.要求有属性“姓名name”,"年龄age","职称post","基本工资salary"
//编写业务方法,introduce(),实现输出一个教师的信息
//编写教师类的三个子类:教师类(Professor),副教授类,讲师类。工资级别分为:教授1.3,副教授1.2,讲师类1.1,在三个子类中都重写introduce()方法
//定义并初始化一个老师对象,调用业务方法,实现对象基本信息的打印功能。
package com.use.encap.homework04;

public class teacher {
    private String name;
    private int age;
    private String post;
    private double salary;
    private double grade;

    public void introduce() {
        System.out.println("name:" + name + "\t" + "age:" + age + "\t" + "post:" + post + "\t" + "salary:" + salary + "\t");
    }

    public teacher(String name, int age, String post, double salary,double grade) {
        this.name = name;
        this.age = age;
        this.post = post;
        this.salary = salary;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getPost() {
        return post;
    }

    public void setPost(String post) {
        this.post = post;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getGrade() {
        return grade;
    }

    public void setGrade(double grade) {
        this.grade = grade;
    }
}
package com.use.encap.homework04;

public class professor extends teacher{

    public professor(String name, int age, String post, double salary,double grade) {
        super(name, age, post, salary,grade);
    }

    @Override
    public void introduce() {
        System.out.println("这是教授类");
        super.introduce();
    }
}
package com.use.encap.homework04;

public class main {
    public static void main(String[] args) {
        professor professor = new professor("狗子",13,"高级职称",17280,1.3);
        professor.introduce();
    }
}
//3.通过继承实现员工工资核算打印功能
//父类:员工类
//子类:部门经理类,普通员工
//部门经理工资 = 1000 + 单日工资 * 天数 * 等级(1.2)
//普通员工工资 = 单日工资 * 天数 * 等级(1.0)
//员工属性:姓名,单日工资,工作天数
//员工方法(打印工资)
//普遍员工及部门经理都是员工子类,需要重写打印工资方法
//定义并初始化普通员工对象,调用打印工资 方法输出工资,定义并初始化部门经理对象,调用打印工资方法输出工资
package com.use.encap.homework05;

public class Employee {
    private String name;
    private double daysal;
    private int workdays;
    private double grade;

    public void printsal() {
        System.out.println(name + "工资:" + daysal * workdays * grade);
    }

    public Employee(String name, double daysal, int workdays, double grade) {
        this.name = name;
        this.daysal = daysal;
        this.workdays = workdays;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getDaysal() {
        return daysal;
    }

    public void setDaysal(double daysal) {
        this.daysal = daysal;
    }

    public int getWorkdays() {
        return workdays;
    }

    public void setWorkdays(int workdays) {
        this.workdays = workdays;
    }

    public double getGrade() {
        return grade;
    }

    public void setGrade(double grade) {
        this.grade = grade;
    }
}
package com.use.encap.homework05;

public class manager extends Employee{

    private double bouns;

    //经理的奖金并不是确定的,所以子啊构造器中不给bonus
    public manager(String name, double daysal, int workdays, double grade) {
        super(name, daysal, workdays, grade);
    }

    public double getBouns() {
        return bouns;
    }

    public void setBouns(double bouns) {
        this.bouns = bouns;
    }

    @Override
    public void printsal() {
        //因为经理的计算方式和Emplee不一样,所以要进行重写
        System.out.println("经理:" + getName() + "的工资是:" + (bouns + getDaysal() * getWorkdays() * getGrade()));
    }
}
package com.use.encap.homework05;

public class worker extends Employee{
    public worker(String name, double daysal, int workdays, double grade) {
        super(name, daysal, workdays, grade);
    }
    @Override
    public void printsal() {
        super.printsal();
    }
}
package com.use.encap.homework05;

public class main {
    public static void main(String[] args) {
        manager manager = new manager("狗子", 100, 20, 1.2);
        manager.setBouns(1000);
        manager.printsal();

        worker worker = new worker("狗子1",100,20,1.1);
        worker.printsal();
    }
}
//4.定义类
package com.use.encap.homework06;

public class Employee {
    private String name;
    private double sal;

    public Employee(String name, double sal) {
        this.name = name;
        this.sal = sal;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public void printsal() {
        System.out.println(name + "年工资是:" + (sal * 12));
    }
}
package com.use.encap.homework06;

public class worker extends Employee{

    //工人,农民,服务员只有基本工资
    public worker(String name, double sal) {
        super(name, sal);
    }

    @Override
    public void printsal() {
        System.out.println("工人");
        super.printsal();
    }
}
package com.use.encap.homework06;

public class main {
    public static void main(String[] args) {
        worker jack = new worker("jack",1000);
        jack.printsal();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值