简介

                                                                       
                                                                       
              二零一七年10月210日  于马那瓜软件园  夜 贰1:4二

上课前要求知道的几点

继承

此起彼伏表示四个门类(子类)派生自(继承于)一个基类型(父类),该品种将持有基类型的全部成员字段和函数(不包涵构造函数和析构函数)。

注意:

  • 派生类继承基类的有着成员,不管是public、private、protected还是其它的,不管是静态的依旧非静态的;可是,就算派生类继承类基类全部的积极分子,基类却只得访问由public和protected修饰的成员(派生类继承了基类全数的字段,但是只可以访问基类中public和protected修饰的积极分子)

    1 class Person
    2 {
    3 private string name = “张三”;
    4 protected int age = 20;
    5 public bool gender = true;
    6
    7 public void ShowInfo_Person()
    8 {
    9 Console.WriteLine(this.name + “:” + this.age + “:” + this.gender);
    10 }
    11 }
    12
    13 class Chinese : Person
    14 {
    15 public void ShowInfo_Chinese()
    1陆 {
    1七 Chinese chinese = new Chinese();
    18 Console.WriteLine(chinese.age);
    1玖 Console.WriteLine(chinese.gender);
    20 //Console.WriteLine(chinese.name);//由于基类中name用private修饰,所以在派生类中不能够访问
    二一 }
    22 }
    贰叁
    二4 class Program
    2伍 {
    贰陆 static void Main(string[] args)
    27 {
    28 Chinese chinese = new Chinese();
    29 chinese.ShowInfo_Person();//输出结果:张叁:20:True 此处通过派生类对象chinese能够调用基类中的ShowInfo_Person()方法,能够评释派生类也继续了private修饰的name字段
    30 Console.ReadKey();
    3一 }
    3二 }

  • 派生类(子类)只可以有一个一向基类(父类);可是后续是可以传递的,例如ClassB派生自ClassA,同时ClassC派生自ClassB,那么ClassC会继承ClassB和ClassA中注明的分子。

    1 class Animal
    2 {
    3 public void Method_Animal()
    4 {
    5 Console.WriteLine(“Animal:—————“);
    6 }
    7 }
    8
    9 class Dog : Animal
    10 {
    11 public void Method_Dog()
    12 {
    13 Console.WriteLine(“Dog:***“);
    14 }
    15 }
    16
    17 class ErHa : Dog
    18 {
    19 public void Method_ErHa()
    20 {
    21 Console.WriteLine(“ErHa:……………”);
    22 }
    23 }
    24
    25 class Program
    26 {
    27 static void Main(string[] args)
    28 {
    29 ErHa eh = new ErHa();
    30 eh.Method_Animal();
    31 eh.Method_Dog();
    32 eh.Method_ErHa();
    33 Console.ReadKey();
    34 }
    35 }

  • C#不协助多重继承,派生类只好有三个一直基类,可是足以兑现多少个接口,并通过兑现多个接口达到多重继承的目标

    1 interface IAnimal
    2 {
    3 void Method_Animal();
    4 }
    5
    6 interface IDog
    7 {
    8 void Method_Dog();
    九 }
    十 //完成多重继承
    11 class ErHa : IAnimal, IDog
    1贰 {
    一三 public void Method_ErHa()
    14 {
    15 Console.WriteLine(“ErHa:……………”);
    16 }
    17
    18 public void Method_Animal()
    19 {
    20 Console.WriteLine(“Animal:**“);
    21 }
    22
    23 public void Method_Dog()
    24 {
    25 Console.WriteLine(“Dog:—————“);
    26 }
    27 }
    28
    29 class Program
    30 {
    31 static void Main(string面向对象3大特点之1,关于面向对象编制程序。[] args)
    32 {
    33 ErHa eh = new ErHa();
    34 eh.Method_Animal();
    35 eh.Method_Dog();
    36 eh.Method_ErHa();
    37 Console.ReadKey();
    38 }
    39 }

  • 布局不协助继承

  • 派生类是对基类的扩展,派生类能够对基类实行成员的增加、重写、覆盖操作

一而再(封装、多态)是面向对象编制程序3大特点之一,继承的思虑正是打消代码的冗余,达成越来越好的重用性。

     
 此前看过1个节目,在那之中有2个情节:二个小女孩对几本古文书籍熟读能背像《三字经》,《诗经》,《笠翁对韵》。主持人吃惊的他的老母,这么小让她接触文言文,小孩子不会觉得难而反感,为啥今后还兴致勃勃。他阿娘的答案里有一句话现今让自家心心念念:“…小孩子的世界里从未难易概念的…”

  1. Javascript继承:继承机制并不曾明确规定,完全由开发者决定最合适的存续格局
  2. 类的原型对象上的保有属性和办法都会被子类拥有
  3. this关键字:什么人调用这一个天性和办法this就指哪个人

  4. 对象冒充艺术贯彻持续(Object Masquerading)

构造函数

  • 派生类不能继续基类的构造函数
  • 当调用派生类的构造函数时,暗许先调用基类的无参构造函数,当基类未有无参构造,须要派生类通过base关键字内定要调用的基类构造函数

    1 class Person
    2 {
    三 public Person()
    四 {
    5 Console.WriteLine(“父类的无参构造函数被调用”);
    6 }
    7 }

    九 class Student:Person
    拾 {
    1一 public Student()
    12 {
    一3 Console.WriteLine(“子类的无参构造函数被调用”);
    1四 }
    一伍 }
    1陆
    17 class Program
    1八 {
    19 static void Main(string[] args)
    20 {
    21 Student stu = new Student();
    22 Console.ReadKey();
    23 }
    24 }

 执行结果:

三番五次从字面上理解,无外乎令人想到某人继承某人的一些事物,四个给三个拿。这么些语义在生活中,就像是

       
是呀,一片白纸,你上哪些颜色,它就接受什么颜色。它从不什么样去对待。就如笔者辈1般,没有接触过机器语言,汇编语言,甚至C语言,直接就是C#。全数咱们半数以上人从没对C#关于直接面向对象思想艺术出来而深感神奇的觉悟。(后续待更)


金沙注册送58 1

 当基类中不存在无参的构造函数时,需求经过base关键字派生类钦命其要调用的基类的构造函数

 1     class Person
 2     {
 3         public Person(string name)
 4         {
 5             Console.WriteLine(name);
 6         }
 7     }
 8 
 9     class Student : Person
10     {
11         public Student()
12         {
13             Console.WriteLine();
14         }
15     }
16 
17     class Program
18     {
19         static void Main(string[] args)
20         {
21             Student stu = new Student();
22             Console.ReadKey();
23         }
24     }

 以上代码执行时会现身以下错误:

家门一而再资金财产,曾外祖父将财产继承给子女,儿女在将财产继承给子孙,有个别东西得以延续有个别的东西只持续给


  1. 目的冒充达成单继承

金沙注册送58 2

固然大家想要使派生类调用基类的有参构造函数,而不是无参构造函数,就能够在派生类中通过base为其要调用的基类构造函数

 1     class Person
 2     {
 3         public Person(string name)
 4         {
 5             Console.WriteLine("姓名:"+name);
 6         }
 7     }
 8 
 9     class Student : Person
10     {
11         public Student(string name, string num)
12             : base(name)
13         {
14             Console.WriteLine("学号:"+num);
15         }
16     }
17 
18     class Program
19     {
20         static void Main(string[] args)
21         {
22             Student stu = new Student("张三", "0002");
23             Console.ReadKey();
24         }
25     }

某人。映射到编制程序此中,其思维也大约这么。

(整理笔记)

金沙注册送58 3

接下去大家通过以下代码,理解一下子类对象的开头化进程

 1     class Person
 2     {
 3         public string name = "默认值:张三";
 4         public string gender = "默认值:男";
 5         public Person(string name, string gender)
 6         {
 7             this.name = name;
 8             this.gender = gender;
 9         }
10     }
11 
12     class Student : Person
13     {
14         public string num = "默认值:0002";
15         public Student(string name, string gender, string num)
16             : base(name, gender)
17         {
18             this.num = num;
19         }
20     }
21 
22     class Program
23     {
24         static void Main(string[] args)
25         {
26             Student stu = new Student("李四", "女", "0004");
27             Console.WriteLine(stu.name);
28             Console.WriteLine(stu.gender);
29             Console.WriteLine(stu.num);
30             Console.ReadKey();
31         }
32     }

 当在Main方法中实例化Student的靶午时,首先在内部存款和储蓄器中分配了空间,内部存款和储蓄器中的开始状态如下图:

金沙注册送58 4

 调用派生类的构造函数,首先会调用基类的构造函数,由于大家在派生类Student中通过base关键字钦赐了派生类要调用的基类构造函数为public
Person(string name,string
gender),所以率先会用传入的参数替换掉基类中成员的暗中同意值,执行到位后,内部存储器中的景况如下:

金沙注册送58 5

 执行完钦命的基类构造函数后,执行派生类本人的构造函数,执行到位后,内部存款和储蓄器中的处境如下:

金沙注册送58 6

迄今截至,派生类对象实例化达成。


面向对象编制程序:

function ClassA(sColor){
    this.name="Lily"
    this.color=sColor;
    this.sayColor=function () {
        console.log(this.color)
    }
}

function ClassB(sColor,sName) {
    //newMethod()之前定义同名属性和方法会被父类覆盖
    // this.name=sName;
    // this.sayColor=function () {
    //     alert(sColor);
    // }

    this.newMethod=ClassA;
    //调用方法后,相当于给B类增加了sColor属性和sayColor方法
    this.newMethod(sColor);

    //newMethod()之后同名方法会覆盖父类
    this.sayColor=function () {
            alert(sColor);
    }
    // 从对象上删除父类构造函数
    delete this.newMethod;

    this.name=sName;
    this.sayName=function () {
        console.log(this.name);
    }
}
var objA=new ClassA("blue");
var objB=new ClassB("red","John");
objA.sayColor(); // blue
objB.sayColor(); // red
objB.sayName(); // John

 透过示范引出继承的功力

壹.构造主意:

Man类后边的“()”,其实就是构造方法。只要您想创设类或组织的实例,必须调用它的构造方法,构造方法负责对类里面包车型大巴字段进行初阶化。(伊始化
int 类型为0,bool类型为 false,char,string类型为“空”….)

金沙注册送58 7

概念:构造方法必须类重名; 构造方法未有再次来到值,但足以有参数;

金沙注册送58 8

构造方法能够有五个重载;  不带参数的构造方法为私下认可构造;

小结: 构造方法的本来面目是一个构造器,是为着类的实例化而发出;

           
构造方法是一种新鲜的措施,它并未再次来到值,它必须与类重名,它只可以在初步化的时候
            被系统活动执行,外部不能够调用;

          假使将构造函数设置为private,则不可能被外表实例化;

         
要是类里面有带参数的构造方法,想调私下认可构造时,必须把暗中认可构造展现写出来;

遇见平常:

金沙注册送58 9

答案如下: 能够

金沙注册送58 10

子类中定义的性质和办法要是在调用this.newMethod()那行代码在此之前,那么子类同名属性和章程会被父类覆盖,反之会覆盖父类同名属性和措施,理由很不难,原来的赋值被新值覆盖

在代码中定义个八个类:Cat猫、Dog狗、Cattle牛。

二.析构措施:

析构方法:
析构方法用于析构类的实例,构造方法用于实例化,分配内部存款和储蓄器空间,而析构方法正
                     好与它反而,用于释放内部存款和储蓄器空间

金沙注册送58 11

金沙注册送58 12

小结:不可能再布局中定义析构方法,只可以对类使用析构方法;

            3个类只好有1个析构方法;

           不恐怕持续或重载析构方法;

            它们是被机关调用的;

           析构方法既未有修饰符,也从不参数;

  1. 金沙注册送58,指标冒充达成多连续

金沙注册送58 13

三.面向对象程序设计:

           
面向进度:分析出解决难题所急需的步子,然后用函数把这么些步骤一步一步完结,使用
                               的时候二个三个一回调用就足以了。

           
 面向对象:把构成事物分解成各样对象,创设对象后用对象调用各自方法以实现缓解问
                               题的指标

           特性:封装,继承,多态,(密封);

         
 OOP(面向对象编制程序)达到软件工程的八个目的:重用性,灵活性,扩充性;

从类图上得以观望浅暗黄标识区域,多少个类的定义出现了大批量的冗余(字段、属性、方法),那么在编写制定代码时就会并发多量的重复代码。

4.面向对象的性状:

装进:是促成面向对象程序设计的第三步,封装正是将数据依旧函数等聚集在四个个的单元中
            (我们称之为类)

           
意义,在于保险依然防备代码(数据)被大家不知不觉中损坏,在于高效的调动各类对象资
            源;

            便是对类成员的重新卷入,那样写更规范:
 Get方法,Set方法对字段的包装,属性对               字段的卷入

金沙注册送58 14

持续:继承用于创立可选取,扩充和修改在别的类中定义的行事的新类。其成员被持续的类称
           
为“基类”,继承那几个成员的类称为“派生类”。派生类只可以有二个平素基类。不过,继承是
           
能够传递的。要是ClassB派生出ClassC,ClassA派生出ClassB,则ClassC会继承  
                  ClassB和ClassA中的成员;

通过在派生类名前面扩充冒号和基类名称,能够钦点基类

金沙注册送58 15

在成立子类的时候,必须求调用父类的构造方法,调用方式有两种:1,隐式调用贰,彰显调用
          (base)    隐式调用用了父类的无参构造器

金沙注册送58 16

(后续)

function ClassC(sColor,sName){
    this.newMethod=ClassA;
    this.newMethod(sColor);
    delete this.newMethod;
    this.newMethod=ClassB;
    this.newMethod(sColor,sName);
    delete this.newMethod;
}
var obj=new ClassC("green","ClassC");

obj.sayName(); //ClassC
obj.sayColor(); // green

试想一下,随着事情职能的扩张,只怕会产出越来越多类,那么冗余(重复的代码)会越来越多。比如出现同等会招致冗余的类:

可见ClassC同时全数ClassA和ClassB的特点
ClassA的同名属性和办法会被ClassB覆盖.同样因为后定义覆盖了先定义

Pig猪、Panda花猫、Sheep羊……等等。那些类同样会有相同的天性:名称、性别、年龄、奔跑(字段、属性、方法)。

二. call()方法完毕一而再

function sayColor(sPrefix,sSuffix){
    console.log(sPrefix+this.color+sSuffix);
}

var obj=new Object();
obj.color="blue";

//会调用sayColor方法
sayColor.call(obj,"The color is "," a very nice color indeed.");

//下面与对象冒充一起使用

function ClassB(sColor,sName) {
    // this.newMethod=ClassA;
    // this.newMethod(sColor);
    // delete this.newMethod;
    //call就是方法调用没啥特别地方,做了上面三条语句做的事
    //调用构造函数
    ClassA.call(this,sColor);

    this.name=sName;
    this.sayName=function () {
        console.log(this.name);
    }
}

叁. apply()方法落成一而再

function sayColor(sPrefix,sSuffix){
    console.log(sPrefix+this.color+sSuffix);
}

var obj=new Object();
obj.color="blue";

// 普通的方法调用
sayColor.apply(obj,new Array("The color is ", " a very nice color indeed."));

function ClassB(sColor,sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    //调用构造函数
    // ClassA.apply(this,arguments)
    ClassA.apply(this,new Array(sColor))
    this.name=sName;
    this.sayName=function () {
        console.log(this.name);
    }
}

var obj=new ClassB("red","Bill");
// 如果特意将ClassB的参数顺序调整ClassA不同,这时就不能用arguments,该使用ClassA.apply(this,new Array(sColor)),感兴趣自己试验一下
// ob.sayColor(); //Bill
obj.sayColor();

小结:call()和apply()让持续变得更舒畅(英文名:Jennifer),查看源码你会发现是Function的原型方法。

 何以消除此类冗余难点 ——
使用持续

4. 原型继承

function object(o) {
    function F() {}
    F.prototype=o;
    return new F();
}
var person = {
    name:"EvanChen",
    friends:["Shelby","Court","Van"]
};

var person1=object(person);
//先从person1对象查找name,没找到会去原型对象上查找
console.log(person1.name);

es伍之后,规范了那种持续,创建对象使用Object.create()

//只传一个参数时
var person1=Object.create(person);
console.log(person1.name);

//传两个参数时
var prop={son:{age:10}};
var person1=Object.create(person,prop);

小结:Object.create传入的首先个参数属性会作为person1的原型属性。第3个参数属性会作为person1对象上的属性

延续的思维:

5. 原型链继承

function ClassA() {}
ClassA.prototype.color="blue";
ClassA.prototype.sayColor=function () {
    console.log(this.color);
}
function ClassB() {

}

ClassB.prototype=new ClassA();

var obj=new ClassB();
obj.sayColor(); //blue
console.log(obj.color); //blue

可知ClassB同时具有了ClassA的品质可方法

上边为ClassB添加更加多原型方法

...
ClassB.prototype=new ClassA();

//下面的属性和方法是在赋值ClassA为新原型之后添加的属性和方法
ClassB.prototype.name="";
ClassB.prototype.sayName=function () {
    console.log(this.name);
}

var classB=new ClassB();
classB.color="red";
classB.name="John";
classB.sayColor(); //red
classB.sayName(); // John

特意建议:

  1. ClassB原型对象上添加的新的习性和方法,请务必添加在ClassB.prototype=new
    ClassA()之后。因为原型已经指向ClassA,旧原型对象被灭绝
  2. 通过修改类的原型对象形式无法落到实处多一而再,因为对象的原型对象仅有多少个
  3. 指标和目的的原型上有同名属性或艺术,优先会利用对象自笔者,若是目的上无此属性,才会动用原型对象上同名属性和方法

当大家定义了三个类,那七个类都设有双重的积极分子(共性)。大家能够将那几个再度的分子单独的提取封装到3个类中,作为这一个全数同等特征类的父类。

陆. 掺杂构造函数和原型链方式达成持续

function ClassA(sColor) {
    this.color=sColor;
}
ClassA.prototype.sayColor=function () {
    console.log(this.color);
}

function ClassB(sColor,sName) {
    ClassA.call(this,sColor);
    this.name=sName;
}

ClassB.prototype=new ClassA();
//为ClassB添加新原型方法
ClassB.prototype.sayName=function () {
    console.log(this.name);
}

var classA=new ClassA("purple");
var classB=new ClassB("red","John");

classA.sayColor(); // purple
classB.sayColor(); // red
classB.sayName(); // John

掺杂继承结合了构造函数创立各类对象具备各自1份属性和原型方法被有着目的共享的帮助和益处

什么不难吗,喜欢的话,援助点个赞O(∩_∩)O谢谢!

将此思考功效于上述的多个类

领取共性:能够直观察出重复的具有共性的类型有:一.字段和性质(年龄、姓名、性别)、2.艺术(奔跑)。

卷入到1个类:怎么定义这么些类?Cat猫、Dog狗、Cattle牛有总而言之共同的特征,正是他俩都以动物,故可以抽象概念一个Animal动物类。

金沙注册送58 17

 

哪些在代码中落实持续

金沙注册送58 18

    class Animal
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private string gender;
        public string Gender
        {
            get { return gender; }
            set { gender = value; }
        }

        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public void Run()
        {
            Console.WriteLine("奔跑。。。");
        }

    }

    class Cat:Animal
    {   
        public void CatchMouse()
        {
            Console.WriteLine("抓老鼠。。。");
        }
    }

    class Dog:Animal
    {
        public void GuardHouse()
        {
            Console.WriteLine("看家护院。。。");
        }
    }

    class Cattle:Animal
    {
        public void Plowland()
        {
            Console.WriteLine("耕田。。。");
        }
    }

通过2个简单易行的  :(冒号)完成了继续关系。

贯彻延续后发出了多少个剧中人物:1.子类(派生类)、2.父类(基类)

代码中子类删除父类提取的重复性成员。

 

落实一连后的关系如下图:

金沙注册送58 19

兑现持续后各种子类仅保留了协调故意的性状,大大收缩了冗余。

 

继续后的能力

子类的共性成员都被父类提取了,那么子类要选取怎么做?

子类继承父类后,将会隐式继承父类的具有成员,但不包蕴构造函数。

在此起彼伏后,访问其父类成员,会受到访问修饰符的限制。故,修饰为private的私家成员不会访问到。

 

接轨的性格

壹.一连的单根性:

  三个子类只好有四个父类,就好比一人唯有一个老爸。

2.持续的传递性:  

   例如, ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC
会继承在 ClassB 和 ClassA 中宣称的积极分子。

次第顺序能够不停向上取。

图例:

金沙注册送58 20


 继续被后的隐私 ——
子类和父类的构造函数(难题)

给父类编写了1个构造函数,示例代码如下:

 1     class Animal
 2     {
 3         public Animal(string name,string gender,int age)
 4         {
 5             this.Name = name;
 6             this.Gender = gender;
 7             this.Age = age;
 8         }
 9 
10         private string name;
11         public string Name
12         {
13             get { return name; }
14             set { name = value; }
15         }
16 
17         private string gender;
18         public string Gender
19         {
20             get { return gender; }
21             set { gender = value; }
22         }
23         
24         private int age;
25         public int Age
26         {
27             get { return age; }
28             set { age = value; }
29         }
30         
31         public void Run()
32         {
33             Console.WriteLine("奔跑。。。");
34         }
35 
36         private void ri()
37         { }
38 
39     }
40 
41     class Cat:Animal
42     {   
43         public void CatchMouse()
44         {
45             Console.WriteLine("抓老鼠。。。");
46         }
47     }
48 
49     class Dog:Animal
50     {
51         public void GuardHouse()
52         {
53             Console.WriteLine("看家护院。。。");
54         }
55     }
56 
57     class Cattle:Animal
58     {
59         public void Plowland()
60         {
61             Console.WriteLine("耕田。。。");
62         }
63     }

 

品尝运营:

金沙注册送58 21

为何会唤醒报这么些荒唐?意思说父类不能够未有一个无参的构造函数。

学过构造函数的应当都会清楚,类在未有点名别的构造函数的景观下,程序默许会指派二个无参的构造函数。

上述的例证由于大家手动添加的十二分构造函数,暗中同意的构造函数就被解除掉了。

在方今不明了原委的情形下,大家品尝补全那么些无参的构造函数,在进展转移代码,此时编写翻译通过未有报错。

 

依据此特征大家得以推断子类和父类的构造函数一定有关联,但一定不是持续关系

 金沙注册送58 22

品味调用刚刚定义的父类无参构造函数,在调用列表并未出示,只显示了类本人的一个无参构造函数。

证实了子类无法继续父类的构造函数。

 

透过调节代码监视子类实例化对象的长河,看它到底和父类的构造函数爆发了怎么样。

透过调节发以后创设子类对象时的代码执行逻辑如下:

金沙注册送58 23

子类会首先去暗中同意执行父类的无参构造函数,然后在举行本身的构造函数

那条结论就很好的诠释了,为啥在上述例子为啥会并发的谬误。而是子类又何以要先去实施父类的构造函数?

解释:

因为子类继承了父类的积极分子,那一项描述只可以声明子类拥有的任务,并不代表子类去实践了。

在规则上要选拔类的积极分子,要求求由此类的实例对象去调用。所以子类要调用到父类的分子,就必须去通过调用

父类的构造函数,在子类的中间创设3个父类的靶子,以便本身去调用父类的成员。

 

总结:

子类始终要运用父类的3个构造函数在友好内部创制三个父类对象,为了调用父类的积极分子。

子类私下认可调用父类的无参构造函数,所以在显示编写3个有参构造函数时造成父类未有了无参构造函数,从而编译出错。


 在子类中动用展现调用父类构造函数

 金沙注册送58 24

作用1:

增强代码重用性,子类无需在类中定义,直接行使父类的。

作用2:

上述例子讲过子类在实例化对象时会调用父类的私下认可无参构造函数,因为子类的目标就是经过父类构造函数创设三个目的。

透过那样展现的调用,那么在父类有未有无参构造函数都无妨关联了。


子类中留存和父类中一样的分子

示例:

金沙注册送58 25

基于VS给大家提醒的音讯,大家得以观看,当代码中存在子类的分子和父类的分子1致的时候,子类的积极分子将父类的积极分子隐藏了。

隐藏过后子类将无法访问到父类的成员。假设是刻意为之,我们得以选取new
关键字显得的印证,从而增强可读性。

指定new关键字:

 金沙注册送58 26

此时提示的波浪线已解决。


 其余注意点

在C#中,全数的类都直接或直接的继续自object类(当大家定义3个类的时候,尽管未有给该类内定继承三个类,那么那个类就持续了object类)。

 

相关文章

网站地图xml地图