• java -se面向对象基础总结



    胡琦光


    一年足够了,二个月JavaSE,半个月html+css+div,一个月的数据库,servlet+jsp一个月,然后SSH框架两个月。然后通起来串一遍,把知识结合起来,再做几个项目练练手,就差不多了。


    1.归类:更好地认识事物,应用事物的归类,为人类创造更高的价值
    ====》利用事物的规律,可以创造新的事物。
    2.对象:具有共同特性,共同结构,共同行为的对象===》这些对象的集合和抽象用一个概念来管理这些对象。
    3.对象与类的关系:
    对象:是实体,是实在存在的一个物体.
    类: 是抽象的,是一个概念。
    所以;类是多个对象的抽象,而对象是类的具体化。

    OOA:面向对象的思想,
    OOD:面向对象的程序设计
    OOP:面向对象编程:三大特性:
    1.封装性:核心:如何封装一个类: 将业务中的数据抽象出来,同时,将业务中数据处理方式方法抽象出来,之后,将他们组成一个整体,用一个名称来管理他们,这个名称就是类。
    封装的目的:a)实现代码的重用 b)黑盒性(即:将数据隐藏起来,让外界不可视,让外界不可直接操作,从而实现了数据的安全性)
    2.继承性:
    3.多态性:
    4.抽象性:


    凡是引用类型的就是一个对象。
    注意:凡是静态的都是属于对象。要使用“引用.“

    方法重载:同一个类中,可以有多个同名的方法,只要方法的参数的类型,个数,顺序不同就可以。
    3.重载的好处:减轻程序员记忆的困难,提高程序编写的效率,(方法的重载只与 “形参”有关 )
    4.调用重载的方法时,是如何区分它们的:。。。
    5.什么情况下用方法的重载:多个方法在完成业务时,其完成业务的性质是一致的,如:都做加法运算。再如调用学生姓名,学号,另外一个人需要调用学生的学号姓名和性别,则不需要再写一个方法了
    5 增加,,,当调用者需要调用同名方法时不需要重新再写一个方法了
    6.构造器也可以重载:即:一个类中可以有多个构造器.
    注:任何一个类,至少有一个构造器。 但有时没有构造器的情况是:自己定义了构造器,则就没有默认构造器了
    7.构造器重载的好处:根据业务需要,可使用不同的构造器来构造具有不同的初始值的需要。
    8.构造方法的好处:构造对象,并实现对象属性的初始化。

    方法重写:重写要求 两个方法的方法签名相同,方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。至于修饰符,范围相同或者比父类的范围小即可。
    1)父类私有方法不能被重写
    2)父类的静态方法不存在重写(因为它是利用 引用调用的,与对象没关系,而多态就是利用父类的引用指向子类的对象),

    super:
    1.super 不是引用类型,指向的不是父类对象, 只是代表当前子类对象中的父类型特征。
    2.super 可以用在什么地方: 1)成员方法, 2)构造方法。
    3.super可以访问父类的属性和方法。
    4.子类的静态方法中不能使用super,(因为成员和构造方法中是调用的属性等,是使用的到对象类型,而静态方法中使用的是引用类型,所以super不适用)

    构造方法:
    1)在继承类中,如果子类中的构造方法没有调用本类的其他构造方法,则子类的默认构造方法会调用父类的默认构造方法。(其实子类的构造方法中有 super())
    2)构造方法在类创建对象时调用,即 new 时调用。


    SSH:框架

    画出内存结构图

    学会使用画图工具》》》》

    绝对值:Math.abs = ||
    开平方:Math.sqrt

    this:
    1.this 的使用方式:
    a) this.属性 或this.方法
    b) this() 或 this(参数列表)
    2.它代表什么
    a)当它以 this. 出现时,它代表 “当前的对象”。
    b)当它以“this()或this(参数列表)”出现时,他代表本类的默认构造器或带相应参数的构造器。
    注意: 当“this”以 “this()”或“this(参数)”的方式出现时,必须在第一行。 即“构造器直接可以相互调用”
    好处:构造的相互调用可以节省代码的书写。

    2)类与类之间的关系:
    a)依赖关系
    b)聚合关系:把多个简单的类组合成一个相对复杂的类。也称之为:整体与部分的关系
    c)继承关系:扩展
    3)开发中,包与包之间的应用 :“import”关键字来实现。其所用的类导入到当前类中 (包的导入)

    OOP: 的

    2.static 的应用。
    a.
    b.它属于类,不属于某个对时,往往需要使用静态变量。
    4.静态变量的访问:
    a.当静态变量前没有private修饰时,通过类名来访问它:“类名.静态变量名”
    b.当静态变量由private修饰时,则必须提供相象,但,可以被所有对象共享。
    c.当类加载时,则静态变量就会存在。
    3.应用中,什么情况下需要静态变量:当涉及共享资源应的静态访问方法。
    5.由static修饰的方法为静态方法
    6.静态方法的特性:
    1)由static修饰
    2)静态方法属于类,不属于对象。但它可以被对象调用。
    7.在什么情况下编写静态方法
    1)当一个方法只操作类中的静态变量时,则这个方法是静态的
    8.工具类: 通常是指该类中只有静态的常量和静态的方法。 便于在使用时,直接通过 类.静态常量或 类.静态方法来实现

    1.静态初始化在什么时候执行,执行多少次?
    静态初始化块在类第一次加载时执行,且只执行一次。
    “this”关键字不能在静态方法中或静态语句块中使用。

    final:最终的变量特性如下:
    1)它有final修饰
    2)它一旦赋值,中途不可再次赋值。
    3)定义了一个最终的实例变量(只读属性)且没有赋值时,则每一个构造器中必须对其初始化。
    4)final 修饰的类无法被继承。
    5)final 修饰的方法无法被覆盖(在继承中 )
    6)final修饰的成员变量一般与static联用,形成 :常量:常量不可变。
    7)final:没有赋初值,则在 “每个” 构造器都要赋值
    8)final修饰的引用类型,该引用不可再重新指向其他java对象,但是final修饰的引用,该引用指向的对象的属性是可以修改的。 final mm m = new mm(a); 不能再次:m = new mm(c); 可以:m.a = "dd";


    toString :是自动的,默认的被调用。
    非静态的成员:(伴随对象而产生,若没有对象,则他们不产生)
    static : 删除static的语句块执行哪个


    1.内部类:包含在一个类的类体的类
    2.外部类:包含了内部类的类
    3.在内部类的方法中,是否可以直接访问外部类的成员(属性和方法) 答案:可以.
    4.在外部类的方法中,是否可以直接访问内部类的成员(属性和方法) 答案:否定。
    注意:在外部类中可以通过对象来直接访问内部类的私有成员变量。 “对象.内部的成员属性”
    5.在外部类之外的类的方法中,如何访问内部类的成员(属性和方法)
    假设:有一个 A为外部类,有一个B为A的内部类,且B类中有一个方法 method()。
    则在A类之外的类的方法中如何访问 method()方法?

    答案:
    1) 创建外部类的对象, 如: A aobj = new A();
    2) 通过外部类的对象去创建一个内部类的对象。
    如: A.B bobj = aobj.new B();

    3) 调用内部类的方法
    如: bobj.method();
    6.静态内部类:
    1)静态内部类可以等同看做静态变量
    2)内部类重要作用,:可以访问外部类中私有的数据。
    3)静态内部类可以直接访问外部类的静态数据,但无法访问成员。

    7.局部内部类:等同于局部变量
    重点:局部内部类在访问局部变量的时候,局部变量必须使用final修饰。
    1)局部内部类不能用访问控制权限修饰符修饰,
    2)内部类不能有静态声明。

    5.匿名内部类:在创建对象时(不论是接口类,还是抽象类),在构造器的小括号末尾加一个{ },之后在{ }中重写父类的方法,所生成的代码就是匿名的内部类。
    1)接口可以实例化吗:不可以;
    2)抽象类可以实例化吗:不可以

    格式化: 例如 :02,11,03,等,当2位数时,会自动补充前面的值, String.format("%02d",month)
    java中的格式化:数据的格式化
    1)格式:System.out.printf("信息<格式控制符>",数据)
    2)格式控制符: %d :十进制整数 %f: 小数 %c :字符格式 %s : 字符串 %02d ,%2d: 控制数据以n位显示 %n.m 以n位显示,小数以m位显示。 %0n.m:总共n位,不足的补0 %-n.m :左对齐, %-n.m 不能和%0n.m同时使用,冲突。

    1)String类的format()方法用于创建格式化的字符串以及连接多个字符串对象
    2)String类的format()方法的使用方式与printf()的方式一样,
    3)String str = String.format("%02d",month), 输出字符串 ,而 printf 是直接输出

    OOP的第二大特性:继承性。
    1)在java中,继承是指通过一个现存的类去扩展一个新类。
    2)另外,在java中,将现存类称之为父类,新生成的是子类。
    3)在java中,一个子类有且只有一个父类,因此,java只支持单继承,不支持多继承,但,可以实现多继承。
    4)父类的私有属性和方法都能被继承,但是不能使用。
    5)父类私有方法不能被重写
    6)父类的静态方法不存在重写(因为它是利用 引用调用的,与对象没关系,而多态就是利用父类的引用指向子类的对象),75
    数组的使用 : 类(和其对象的数组) StudentTest[] ss = {s1, s2, s3, s4, s5}; 或: int[3] a = {1,2,3};
    注意:数组是引用类型,一个数组内的数据就是一个对象。


    多态:
    1。什么是多态:
    注意: 多态中,父类的引用指向子类的对象时,如果调用子类的方法,则方法必须重写才能 够调用。
    1)一个父类有多个子类,子类的对象,同种的多个对象在接收到某个信息时,却产生了不同的反映和效果
    2)多态的分类:
    a.静态的多态:方法的重载
    b.动态的多态(主要):由父类的对象变量来管理不同的子类对象,当子类对象接受到同一个信息时,却可以产生不同的反映和效果。
    2.引用类型的转换:
    1)自动转换(向上转型):父类的对象变量可以引用子类的对象。
    a )父类的对象变量可以访问自己的属性、方法,也可以访问子类继承来的属性和方法。但是如果父类的对象变量去访问子类特有的属性,则出错。
    那怎么办呢: 需要向下转型:

    2)强制转换(向下转换):将父类的对象还原为子类的引用。
    目的:向下转型就是为了访问子类对象特有的成员(属性和方法)
    例如:Father f1 = new Son() ; 此时,method()是子类特有的方法
    向下转化格式: 子类名 变量名 = (子类名)父类的对象变量
    Son s1 = (Son)f1; 所以 s1.method(); 成立

    注意:由于父类的对象变量可以引用子类的对象,而Object类是所有类的祖先,所以,Object类的对象变量可以引用任何类的对象。
    注意:向下转型必须有一个前提:父类的对象引用了子类的对象,即:发生了多态。因此,为了确保不发生问题,往往向下转型时,需要先判断,后向下转型。


    父类可以调用子类继承的属性:????


    OOP三大特性:
    1.封装目的: 1.重用性 2.安全性
    2.继承目的: 1.子类生成的高效性, 2.极大地提高了父类代码的重用性
    3.多态目的: 1.统一性(父类管理所有子类的对象) 2.提高了应用的高效性。

    抽象类:
    1.在java中 ,只有方法头部,没有方法体且被abstract关键字修饰,这种方法称之为抽象方法。
    理解:只知道做什么,不知道如何做。因此一个类中一旦拥有某一个抽象方法,则一定是抽象类。
    注意:抽象类不一定有抽象方法,但是抽象方法一定会在抽象类中。

    2. 1)它一定被 abstract 关键字修饰
    2)抽象类不可实例化,即:不能用它来创建对象。
    3)抽象类必须有子类,且子类必须对来自抽象类的所以抽象方法,要一一实现其抽象方法,否则,子类也是抽象的。
    4)在封装类时,若发现其中有一个或一个以上的方法只知道做什么,不知道如何做,此时,这个类就是一个抽象类。

    finalClass :最终类
    1.它由final修饰。
    2.最终类不可被继承。即:防继承。 例如:String "ABC",
    在实际工作中,发现一个类的所有成份均已确定,不再有什么扩展。即:不可能有子类,则,此时,可以将这个类定义为最终类。

    3.最终方法:
    由final修饰的具体方法称之为最终方法。
    4.最终方法的特性: (可继承,(感觉是废话)), 不可被重写。 即:防重写。

    抽象类:
    1.如何定义抽象类:class关键字前加:abstract
    2.抽象类无法被实例化,
    3.虽然抽象类无法被实例化,但是抽象类也有构造方法,该构造方法是给子类创建对象用的。
    4.抽象类中可以定义抽象方法:在方法的修饰符类别中添加abstract关键字,并且抽象方法应该以“;”结束,不能带有{ },例如:public abstract void m1();
    5.抽象类中不一定有抽象方法,但抽象方法必须出现在抽象类中,
    6.一个非抽象的类继承抽象类:必须将抽象类中的抽象方法重写;或者子类也是抽象类。
    7.final和abstract不能同时存在,

    8抽象方法格式: 如果是抽象方法,则只声明,不要实现; 如果是非抽象方法,则需要实现。
    注意: 一个非抽象的类继承抽象类:必须将抽象类中的抽象方法重写;或者子类也是抽象类也行。
    abstract public class Test {
    abstract public int add(int x, int y);
    public int add1(int x, int y) {
    return x + y;
    }
    }


    接口:
    要求:
    1、定义接口使用关键字:interface
    2、接口中方法必须是公开方法
    3、接口中的方法不能有方法体,即不能有方法体

    1.定义:接口实际上就是一种规则,是一种标准,是一种统一的要求。例如:普通话,它就是一个接口,他实际是一套汉子的标准发音。
    2.在java中,接口由interface关键字来定义,同时,接口只包含两种成份,
    1)公共的静态的常量;

    2)公共的抽象的方法。
    3.理解:接口实质上是抽象类的彻底抽象。
    问:为什么需要接口?
    答:java中,java只支持单继承,不支持多继承;因此,为了实现多继承这种现象,专家提供了接口。 即:通过接口可以实现多继承这种现象
    例如: public class 子类 extends 父类 implements 接口1(干爹),接口2(干爹),....{...}
    注意:当一个类实现了某个接口时,则这个类必须对来自接口的所以抽象方法要一一重写;否则,该类就必须作为抽象像类看待。

    4.生成一个接口,如:public interface 接口名{...}
    5.接口的应用:
    1).现存接口的应用:
    1)导入(import)接口;
    2)编写一个类且实现(implements)该接口
    3)在该类中需要重写来自接口的所以抽象方法
    4) 测试应用

    2)自定义接口: 公共的静态的常量 和 公共的抽象的方法
    1)自定义接口(interface)接口;
    2)导入(import)接口;
    3)实现(implements)接口
    4)在实现类中重写来自接口的所有抽象方法。
    5)测试应用(注意:在测试应用中需要人为调用重写后的方法)

    3 自定义接口格式:
    public interface 接口名 [extends 父接口1,父接口2...]{ ... }

    注意:在定义接口时,java规定:一个接口可以没有父接口;也可以只有一个父接口;还可以有多个父接口。
    public interface Arithmatic{
    double PI = 3.14; // 省略了三个单词 public static final double PI = 3.14;
    int add(int x, int y); //省略了两个关键字 public static int add(int x, int y);
    }

    接口作用:
    1.可以使项目分层,所有层都面向接口开发,开发效率提高了。
    2.接口使代码和代码之间的耦合度降低,就像内存条和主办的关系,变得“可插拔”,可以随意切换。
    注意:接口和抽象都能完成某个功能,优先选择接口。因为接口可以多实现,多继承。并且一个类除了实现接口之外,还可以去继承其他类(保留了类的继承)
    ??不是太懂
    注意: 接口是完全化的抽象类,

    ======================================================================

    1。在java中,存在一个超根类(祖先类),它来自java。lang.Object类。因此,当生成一个类时,若没有明确指定其父亲是谁,则系统会将Object类作为其父类。相当于:public class 类名 extends Object{ }

    2.Object类中常用方法:
    1)String toString(); 此方法将对象的信息以字符串方式反馈,且,此方法是自动调用的。 因此,当子类的对象要展现自己的个性时且通过对象变量之间展现自动的个性信息,再次调用toString方法。

    2)boolean equals( ) 此方法来判断两个对象是否完全相等,使用:boolean flag = (obj1.equals(obj2)) ; 结果 :false,地址不同, true, 地址相同。

    3)结论:凡是自定义的对象,要判断相等,则必须重写equals()方法,为对象判断相等提供依据。
    因此,建议:凡是自定义类,尽量去重写equals()方法。
    4)字符段要判断是否相等时,可以使用"equals()"来判断。


    注意:boolean 的类型的成员变量以后的set,get方法使用 不要再使用 public void setSex(){ }
    而是 public void isSex(){ } 和 public boolean isSex(){ }

    字符串:
    1 在java中,字符串通常有java.lang.String类来管理
    2 java中的特殊串:
    1)只有一对双引号,其中没有任何字符,则这个字符串称之为空串(长度为零的串)
    2)String str = ""; String str = null;
    3 字符串特性:
    1)字符串是引用类型,一个字符串就是一个对象。
    2) 例如:字符串中的字符索引从“0”开始,
    3)由于字符串是对象,则它就拥有一些属性和一些方法。
    4)在java中,用一对双引号括起来的字符串,有多个时且他们完全相等,则它们实际是一个。即:共享的,变通一下:对象常量。
    5)字符串是不变的。
    4 字符串的常用方法:
    length(); 长度
    charAt(n) : 获取第n个位置上的字符。
    substring(n) 获取从 n 为开始,到末尾上的所有字符组成一个字符串
    substring(n,m) 获取从 n 为开始,到 m 位的所有字符组成一个字符串
    indexOf(s) 在串中查找‘s’,若存在,则反馈它的位置编号;反之,反馈一个负数
    indexOf(abc) 在串中查找"abc",若存在,则反馈它第一次出现的位置编号;反之,反馈一个负数
    lastIndexOf(abc) 在串中查找"abc",若存在,则反馈它最后一次出现的位置编号;反之,反馈一个负数
    boolean s1.startsWith(String str) 判断s1是否是以 str 开始
    boolean s1.endsWith(String str) 判断s1是否是以 str 结束
    boolean obj1.equals(obj2) 判断2个数是否完全相等。
    boolean ob1.equanlsIgnoreCase(obj2) 忽略大小写进行比较
    int obj1.compareTo(obj2) 比较两个字符串的大小 >,< , == 0时 :则obj1与obj2 对象相等。例如:“ABC”,“AbC”,比到B,b时就停止了,不再往下进行了。
    trim(); 去掉字符串前后的空格“必须是英文空格”,字符串中间的空格去不掉。
    replace(s1,s2) :字符串或单个字母 s2 替换 s1
    String.valueOf() ;将给定的数据转变成字符串;
    例如:String a1 = String.valueOf(2.2f);
    也可以:String a2 = 2.33f + "";

    注意:相同的字符串地址是相同的

    Object类:
    1)Object类是所有java类的根基类。
    2)如果类中未声明使用extends继承何种类,则默认基类为Object类。
    3)里面的 toString 方法:是Object自带的系统方法,因为它的功能不完善,所有它就是要被重写的。
    例如:创建类的对象p Person p = new Person("duende"); System.out.println(p.toString); 和 System.out.println(p); 对象p总会调用重写的toString方法。

    equals:
    1) ==比较的是2个对象的地址,而equals比较的是2个对象的内容。
    例如; Studentt t = new Studentt("dd");
    Studentt tt = new Studentt("dd");
    boolean f = t.equals(tt); System.out.printlnt.equals(f)); // true
    boolean ff = t == tt; System.out.printlnt.equals(ff)); //false

    2)当是对象调用的时候,是比较对象的内存地址:但有时对象调用时,有时需要重写equals方法,比较equals里面的具体内容,就需要强制类型转换:
    例如:主函数里面 Studentt t = new Studentt("dd");
    Studentt tt = new Studentt("dd");
    boolean f = t.equals(tt);

    public boolean equals(Object obj){
    Studentt t = (Studentt)obj;
    if(name == t.name){
    return true;
    }else{
    return false;
    }
    }
    3) 注意://字符串比较不能直接用 “==”,而应该使用 “.equals”来比较。
    String name;
    if(name == t.name){ // 不正规(但是也没错)
    if(name.equals(t.name)){ // 正规的。


    finalize方法: 自动调用,回收垃圾对象的方法
    1.finalize方法对每个对象都有 ,
    2.finalize方法不需要程序员去调用,由系统自动调用。
    3.java对象如果没有更多的引用指向它,则该java对象成为垃圾数据,等待垃圾回收器的回收,垃圾回收器在回收这个java对象之前会自动调用该对象的finalize方法。

    hashCode方法:
    1.hashCode方法返回的是该对象的哈希码值
    2.java对象的内存地址经过哈希算法得出的 int 类型的数值。

    package: 软件包机制:
    import:
    1.包是为了解决类的命名冲突,在类前加命名空间(机制)
    2.package定义的格式,通常采用公司域名倒叙方式。
    例如:com.bjsxt.Day30.Person; Person 是Day30项目中其中一个模块。
    3.完整的类名是带有包名的。
    4.doc 编程遵循: javac -d 生成路径 java源文件路径
    5.java.lang;软件包下所有类不需要手动导入,系统自动导入。其他,如:java.util.Date; java.Io。

    private: 只能在本类中访问
    public : 可以在任何位置访问
    protected: :本类中,同一个包下。不同包下不行,但是子类中可以(但是我测试了,不行啊)
    default(默认不写) : 本类,同一个包下。不同包下不行,


    Day31:
    泛华关系: 继承
    实现关系: 接口和接口类的实现
    关联关系:1)在当前类中含有其他类的引用, 2)在当前对象中含有指向其他对象的引用。(即类的聚合)

    _is_a: 继承
    _is like a:接口和接口类的实现
    _has_a: 关联

    finally语句块:
    1.finally语句块可以直接和try语句块联用,try...finally...
    2.try...catch...finally 也可以
    3.在finally语句块中的代码是一定会执行的。但是:只有在执行finally语句块之前退出了,则finally就不会执行了。System.exit(0);
    注意: 例子:
    public static int m(){
    int i = 10;
    try{
    // int temp = i; //先执行 try , 在执行finally,最后return i,(return i,相当于把i赋给了一个临时变量)。
    return i; // 10;
    }finally{
    i++;
    System.out.println(i); //11
    }
    }
    4.finally语句块是一定会执行的,所以通常在程序中为了保证某资源一定会释放,所以一般在finally语句块中释放资源。例如:
    public static void main(String[] args) {
    FileInputStream fis = null;
    try{
    fis = new FileInputStream("Test.java"); // 判断是否有异常对象,
    }catch(FileNotFoundException e){
    // e.getMessage();
    e.printStackTrace();
    }finally{
    if(fis != null){ // 如果异常不为空的话,
    fis.close(); // 关闭它,
    }catch(IOException e){
    e.printStackTrace();
    }
    }
    }

    final, finalize, 和 finally 的区别。
    1.final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
    2.finally是异常处理语句结构的一部分,表示总是执行。
    3.finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

    手动抛出异常:throw 106集_十分重要???

    重写的方法不能比重写的方法抛出更宽泛的异常。 即:子类永远无法抛出比父类更多的异常。


    instanceof: instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例
    例如:

    提问:字符串什么时候是共享的。。。。。。。。
    学习学的是什么啊,一知半解。。。。。。。。。。


    程序追求“高内聚,低耦合”

    匿名的内部类(重点)

    类与类的聚合关系???

    多态: 父类的引用指向子类的对象。
    1.好处:统一性,高效性。

    接口多练练,不熟。
    之前的栈、堆,那个画图视频再看看??
    protected: :本类中,同一个包下。不同包下不行,但是子类中可以(但是我测试了,不行啊)
    匿名内部类:?? 93节(重要)
    递归调试:、、??

    java可以实现多继承,如何实现 ??
    API文档,jdk,????
    注意:数组是引用类型,一个数组内的数据就是一个对象。?? 字符串也是引用类型。还有哪些 “abc” == “abc”
    static ???共享??
    静态包的导入

  • 相关阅读:
    [LeetCode] Wiggle Sort
    [LeetCode] Perfect Squares
    [LeetCode] Minimum Window Substring
    [LeetCode] Valid Sudoku
    [LeetCode] Sudoku Solver
    [LeetCode] First Bad Version
    [LeetCode] Find the Celebrity
    [LeetCode] Paint Fence
    [LeetCode] H-Index II
    [LeetCode] H-Index
  • 原文地址:https://www.cnblogs.com/lgf428/p/5784749.html
Copyright © 2020-2023  润新知