有关面向对象编制程序,面向对象三大特色之一

有关面向对象编制程序,面向对象三大特色之一。简介

                                                                       
                                                                       
              201七年二月226日  于马斯喀特软件园  夜 二一:4二

教学前要求知道的几点

继承

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

注意:

  • 派生类继承基类的有所成员,不管是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()
    16 {
    1柒 Chinese chinese = new Chinese();
    18 Console.WriteLine(chinese.age);
    1九 Console.WriteLine(chinese.gender);
    20 //Console.WriteLine(chinese.name);//由于基类中name用private修饰,所以在派生类中无法访问
    2一 }
    2二 }
    2三
    贰4 class Program
    二5 {
    26 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();
    玖 }
    十 //达成多重继承
    1一 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[] args)
    32 {
    33 ErHa eh = new ErHa();
    34 eh.Method_Animal();
    35 eh.Method_Dog();
    36 eh.Method_ErHa();
    37 Console.ReadKey();
    38 }
    39 }

  • 组织不帮忙继承

  • 派生类是对基类的恢弘,派生类能够对基类进行成员的增加、重写、覆盖操作

持续(封装、多态)是面向对象编制程序叁大特征之壹,继承的怀念就是打消代码的冗余,达成更好的重用性。

     
 之前看过2个剧目,在那之中有一个内容:三个小女孩对几本古文书籍熟读能背像《三字经》,《诗经》,《笠翁对韵》。主持人吃惊的她的阿娘,这么小让他接触文言文,小孩子不会认为难而反感,为何今后还兴致勃勃。他老妈的答案里有一句话现今让本身难忘:“…儿童的世界里未有难易概念的…”

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

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

构造函数

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

    一 class Person
    二 {
    三 public Person()
    四 {
    5 Console.WriteLine(“父类的无参构造函数被调用”);
    陆 }
    柒 }

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

 执行结果:

继续从字面上理解,无外乎令人想到某人继承某人的一点事物,三个给1个拿。那个语义在生活中,就像是

       
是啊,一片白纸,你上什么样颜色,它就承受什么颜色。它未有怎么去对待。就如我辈壹般,未有接触过机器语言,汇编语言,甚至C语言,直接便是C#。全部大家大多数人绝非对C#有关直接面向对象思想艺术出来而感到神奇的觉醒。(后续待更)


美高梅开户网址 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. 对象冒充实现单继承

美高梅开户网址 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     }

某人。映射到编制程序其中,其考虑也大约如此。

(整理笔记)

美高梅开户网址 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的对象时,首先在内部存款和储蓄器中分配了空中,内部存储器中的起初状态如下图:

美高梅开户网址 4

 调用派生类的构造函数,首先会调用基类的构造函数,由于我们在派生类Student中通过base关键字钦命了派生类要调用的基类构造函数为public
Person(string name,string
gender),所以首先会用传入的参数替换掉基类中成员的暗中认可值,执行到位后,内部存款和储蓄器中的情况如下:

美高梅开户网址 5

 执行完钦定的基类构造函数后,执行派生类自个儿的构造函数,执行到位后,内部存储器中的情形如下:

美高梅开户网址 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类型为“空”….)

美高梅开户网址 7

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

美高梅开户网址 8

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

小结: 构造方法的原形是2个构造器,是为着类的实例化而发出;

           
构造方法是1种特殊的点子,它从不重回值,它必须与类重名,它不得不在开首化的时候
            被系统自动执行,外部不能调用;

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

         
假诺类里面有带参数的构造方法,想调私下认可构造时,必须把暗中认可构造突显写出来;

碰到小意思:

美高梅开户网址 9

答案如下: 能够

美高梅开户网址 10

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

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

贰.析构措施:

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

美高梅开户网址 11

美高梅开户网址 12

总计:无法再布局中定义析构方法,只好对类使用析构方法;

            三个类只好有一个析构方法;

           不能继续或重载析构方法;

            它们是被活动调用的;

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

  1. 对象冒充达成多延续

美高梅开户网址 13

3.面向对象程序设计:

           
面向进度:分析出消除难题所供给的手续,然后用函数把那些手续一步一步完成,使用
                               的时候1个三个3回调用就能够了。

           
 面向对象:把构成事物分解成各样对象,创立对象后用对象调用各自方法以达到缓解问
                               题的目的

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

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

从类图上能够见到深紫红标识区域,四个类的概念出现了大气的冗余(字段、属性、方法),那么在编写制定代码时就会并发大批量的再次代码。

四.面向对象的性状:

包裹:是达成面向对象程序设计的第1步,封装就是将数据依旧函数等聚集在三个个的单元中
            (大家称之为类)

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

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

美高梅开户网址 14

继续:继承用于创制可选择,扩大和改动在其余类中定义的行为的新类。其成员被接续的类称
           
为“基类”,继承这个成员的类称为“派生类”。派生类只好有3个直接基类。可是,继承是
           
能够传递的。要是ClassB派生出ClassC,ClassA派生出ClassB,则ClassC会继承  
                  ClassB和ClassA中的成员;

透过在派生类名前边增添冒号和基类名称,能够钦赐基类

美高梅开户网址 15

在成立子类的时候,必必要调用父类的构造方法,调用方式有三种:一,隐式调用2,呈现调用
          (base)    隐式调用用了父类的无参构造器

美高梅开户网址 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()让持续变得更舒适,查看源码你会发觉是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);

es5随后,规范了那种持续,创立对象使用Object.create()

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

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

总括:Object.create传入的率先个参数属性会作为person壹的原型属性。第二个参数属性会作为person一对象上的习性

再三再四的沉思:

伍. 原型链继承

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. 对象和对象的原型上有同名属性或艺术,优先会采用对象自作者,若是指标上无此属性,才会使用原型对象上同名属性和办法

当大家定义了多个类,那两个类都设有双重的成员(共性)。大家能够将那些重新的分子单独的提取封装到二个类中,作为这几个富有同等特征类的父类。

六. 掺杂构造函数和原型链格局实现持续

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

掺杂继承结合了构造函数创立各种对象拥有各自壹份属性和原型方法被全部指标共享的长处

怎么着简单吗,喜欢的话,支持点个赞O(∩_∩)O谢谢!

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

领到共性:可以直阅览出重复的全部共性的档次有:一.字段和属性(年龄、姓名、性别)、贰.艺术(奔跑)。

装进到三个类:怎么样定义这一个类?Cat猫、Dog狗、Cattle牛有可想而知共同的特色,正是她们都是动物,故能够抽象概念三个Animal动物类。

美高梅开户网址 17

 

何以在代码中贯彻持续

美高梅开户网址 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.父类(基类)

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

 

落到实处持续后的关联如下图:

美高梅开户网址 19

兑现持续后各类子类仅保留了协调有意的特征,大大收缩了冗余。

 

后续后的力量

子类的共性成员都被父类提取了,那么子类要运用如何做?

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

在持续后,访问其父类成员,会遭到访问修饰符的限制。故,修饰为private的私人住房成员不会访问到。

 

此起彼伏的特性

一.持续的单根性:

  2个子类只可以有一个父类,就好比一个人唯有1个老爸。

二.接续的传递性:  

   例如, ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC
会继承在 ClassB 和 ClassA 中扬言的分子。

各样顺序能够不停向上取。

图例:

美高梅开户网址 20


 继承被后的秘密 ——
子类和父类的构造函数(难题)

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

 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     }

 

品味运维:

美高梅开户网址 21

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

学过构造函数的应有都会清楚,类在未曾点名别的构造函数的情况下,程序暗中同意会指派2个无参的构造函数。

上述的事例由于大家手动添加的百般构造函数,默许的构造函数就被破除掉了。

在目前不清楚原因的动静下,我们品尝补全那些无参的构造函数,在进行转变代码,此时编写翻译通过没有报错。

 

依照此特征我们得以测算子类和父类的构造函数一定有涉及,但一定不是三番四次关系

 美高梅开户网址 22

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

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

 

通过调节代码监视子类实例化对象的进度,看它到底和父类的构造函数产生了怎么着。

通过调节发今后创造子类对象时的代码执行逻辑如下:

美高梅开户网址 23

子类会首先去私下认可执行父类的无参构造函数,然后在执行自身的构造函数

那条结论就很好的分解了,为何在上述例子为啥会产出的谬误。而是子类又为啥要先去实践父类的构造函数?

解释:

因为子类继承了父类的分子,这一项描述只好证实子类拥有的职务,并不意味子类去履行了。

在规范上要选用类的成员,必需求通过类的实例对象去调用。所以子类要调用到父类的分子,就务须去通过调用

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

 

总结:

子类始终要运用父类的一个构造函数在友好之中创制二个父类对象,为了调用父类的分子。

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


 在子类中应用突显调用父类构造函数

 美高梅开户网址 24

作用1:

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

作用2:

上述例子讲过子类在实例化对象时会调用父类的暗中同意无参构造函数,因为子类的目标就是经过父类构造函数创制三个对象。

经过如此展现的调用,那么在父类有未有无参构造函数都没什么关联了。


子类中设有和父类中平等的成员

示例:

美高梅开户网址 25

依照VS给我们提醒的新闻,大家得以看到,当代码中留存子类的分子和父类的积极分子1致的时候,子类的积极分子将父类的成员隐藏了。

暗藏过后子类将不大概访问到父类的分子。就算是刻意为之,我们得以运用new
关键字显得的表达,从而增强可读性。

指定new关键字:

 美高梅开户网址 26

那会儿提醒的波浪线已清除。


 此外注意点

在C#中,全数的类都直接或直接的存在延续自object类(当大家定义三个类的时候,如果未有给该类钦点继承3个类,那么那一个类就接二连三了object类)。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图