解释JavaScript基于面向对象的继承
1.face对象继承机制这个例子通过使用UML很好地解释了继承机制。解释继承机制最简单的方法就是用一个经典的例子,就是几何形状。实际上,只有两种几何形状,即椭圆(圆形)和多边形(有一定数量的边)。圆是一种椭圆,只有一个焦点。三角形、矩形和五边形是各种不同边数的多边形。正方形是一种所有边都等长的矩形。这就构成了一个完美的继承关系,很好地解释了面向对象的继承机制。在这个例子中,形状是椭圆和多边形的基类(通常我们也可以称之为父类,所有的类都继承自父类)。椭圆有一个亏格(焦点),表示椭圆有多少个焦点。圆继承椭圆,所以圆是椭圆的子类,椭圆是圆的超类。同样,三角形、矩形和五边形都是多边形的子类,多边形是它们的超类。最后,正方形继承了矩形。最好用图来解释这种继承关系,这就是UML(统一建模语言)发挥作用的地方。UML的主要用途之一是直观地表示复杂的对象关系,如继承。下图是解释形状及其子类之间关系的UML图:
在UML中,每个框代表一个类,由类名描述。三角形、矩形和五边形顶部的线段汇聚并指向形状,表明这些类是从形状继承而来的。同样,从正方形指向矩形的箭头说明了它们之间的继承关系。第二,要实现ECMAScript的继承机制,就要用ECMAScript来实现继承机制,可以从要继承的基类开始。所有开发人员定义的类都可以用作基类。出于安全原因,本地类和宿主类不能用作基类,这可能会阻止公众访问已编译的浏览器级代码,因为这些代码可能会被用于恶意攻击。选择基类后,您可以创建它的子类。是否使用基类完全由您决定。有时,您可能想创建一个不能直接使用的基类,但它仅用于为子类提供一般功能。在这种情况下,基类被视为抽象类。尽管ECMAScript没有像其他语言那样严格地定义抽象类,但有时它确实会创建不允许使用的类。通常,我们称这种类为抽象类。创建的子类将继承超类的所有属性和方法,包括构造函数和方法的实现。请记住,所有的属性和方法都是通用的,因此子类可以直接访问这些方法。子类也可以添加不在超类中的新属性和方法,或者覆盖超类的属性和方法。由于JS不是正统的面向对象语言,有些名词需要更改。三、ECMAScript继承的方式在ECMAScript语言中,继承的类(基类)称为超类型,子类(或派生类)称为子类型。像其他函数一样,在ECMAScript中实现继承的方式不止一种。这是因为JavaScript中的继承机制没有明确定义,而是通过模仿实现的。这意味着所有的继承细节并不完全由解释器处理。作为开发人员,您有权决定最合适的继承方法。这里有一些具体的继承方法给你。(1)原型链的继承最初用于ECMAScript中的原型链。上一篇博文已经介绍了如何原型化对象。原型链以这种方式扩展,并以一种有趣的方式实现继承机制。原型对象是所有要实例化的对象所基于的模板。总之,原型对象的任何属性和方法都会传递给该类的所有实例。原型链使用这个函数来实现继承机制。让我们看一个例子:
函数A() {//supertype a中不能有this.color='red '的参数;this . show color=function(){ return this . color;};};函数B() {//子类型B this.name=' Johnthis . show name=function(){ return this . name;};};b . prototype=new A();//子类型b继承超类型A,通过原型形成链var A=new A();var b=新B();document . write(a . show color());//输出:blue document . write(b . show color());//输出:red document . write(b . show name());//输出:John,在原型链中,instanceof运算符以一种独特的方式运行。对于b的所有实例,instanceof是a,b都返回true。在ECMAScript的弱类型世界中,这是一个非常有用的工具,但是在使用对象模拟时不能使用它。例如:
var b=新B();文档. write(A的b实例);//输出:truedocument.write (b的b实例);//输出:true使用原型链实现继承,但这种方式不能共享和子类型将参数传递给超类型。我们可以通过构造函数(即对象的模拟)来解决这两个问题。(2)对象模拟对象模拟的原理如下:构造函数使用这个关键字给所有的属性和方法赋值(即对象声明的构造函数)。因为构造函数只是一个函数,你可以把A构造函数变成B的方法,然后调用它。b将接收A的构造函数中定义的属性和方法。例如,重写上面的示例,以下列方式创建对象A和B:调用()方法。
函数A(颜色){//创建一个超类型A this.color=Colorthis . show color=function(){ return this . color;};};函数B(Color,Name) {//创建子类型B . a .调用(this,Color);//对象冒充这个. Name=Name;//新添加的属性this . show name=};var a=新A('蓝色');var b=新B('red ',' John ');document . write(a . show color());//输出:blue document . write(b . show color());//输出:red document . write(b . show name());//输出:上面John apply()方法和call()方法唯一的区别就是b子类型中的代码:A.call(this,arguments);//对象假装将参数传递给超类型。当然,只有当超类型中参数的顺序与子类型中参数的顺序完全一致时,才能传递参数对象。如果没有,您必须创建一个单独的数组,并按照正确的顺序放置参数。虽然使用对象模拟解决了共享和传递参数的问题,但是没有原型就更不可能重用,所以我们结合以上两种方法,即原型链和对象模拟,来实现JS继承。(3)混合模式这种继承模式使用构造函数来定义类,而不是任何原型。对象模拟的主要问题是必须使用构造函数,这不是最好的选择。但是,如果使用原型链,则不能使用带参数的构造函数。开发者如何选择?答案很简单,两者并用。由于这种混合方法使用原型链,instanceof运算符仍然可以正确运行。在上一篇文章中,创建对象的最好方法是用构造函数定义属性,用原型定义方法。这种方法也适用于继承机制,即对象假装继承构造函数的属性,原型链继承原型对象。用这两种方法重写前面的例子,代码如下:
函数A(Color){ this . Color=Color;};a . prototype . show color=function(){ return this . color;};函数B(颜色,名称){ A.call(这个,颜色);//对象模拟了这个,Name=Name;};b . prototype=new A();//使用原型链继承b . prototype . show name=function(){ returnthis . name;};var a=新A('蓝色');var b=新B('red ',' John ');document . write(a . show color());//输出:blue document . write(b . show color());//输出:red document . write(b . show name());//输出:John的继承方式与创建对象的方式有关。推荐的继承模式也是原型链和对象模拟的混合。使用这种混合方法可以避免一些不必要的问题。在阅读本文时,我们必须看一看前面创建对象的方法:解释JavaScript的面向对象创建(1)和JavaScript的面向对象创建(2)。
以上就是本文的全部内容,希望对大家的学习有所帮助。
版权声明:解释JavaScript基于面向对象的继承是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。