zoukankan      html  css  js  c++  java
  • JavaScript中的面向对象编程(二)

    对象冒充,apply()方法 Call()方法 原型链(利用prototype对象来实现.

     

     

     

    Javaspript的继承

    JavaScript中的继承

    特点:

    1ECMAScript中并没有像其他语言那样严格地定义抽象类.

    2、所有类的方法都是public的作用域

    3、继承的方式不止一种,支持多重继承

    严格讲,javascript的继承机制并不是明确规定的,而是通过模仿实现的。

    对象冒充

       其原理如下:构造函数使用this关键字给所有属性和方法赋值.因为构造函数只是一个函数,所以可使用ClassA的构造函数成为ClassB的方法,然后调用它.ClassB就会收到ClassA的构造函数中定义的属性和方法.

    eg1:

    function ClassA(sColor){

        this.color = sColor;

        this.sayColor = function(){

            alert(this.color); } }

    function ClassB(sColor){

       this.newMethod = ClassA;//定义新的属性指向classA

       this.newMethod(sColor);

       delete this.newMethod; 把这个属性删除掉,相当于classBclassA继承

    }

    注意:所有的新属性和新方法都必须在删除了新方法的代码行后定义.否则,可能会覆盖超类的相关属性和方法.

    function ClassA(sColor){

        this.color = sColor;

        this.sayColor = function(){

            alert(this.color); } }

    function ClassB(sColor,sName){

        this.newMethod = ClassA;

        this.newMethod(sColor);

       delete this.newMethod;

        this.name = sName;//定义新方法新属性需要先删除覆盖过来的超类

        this.sayName = function(){

              alert(this.name); }}

    //call

    Var objA = new ClassA(“red”); Var objB = new ClassB(“blue”,”zhang”);

    objA.sayColor();   //output “red”;

    objB.sayColor();   //output “blue”;

    objB.sayName(); //output “zhang”;

     

     

     

    模仿多重继承

    eg:

    function ClassA(sColor)                        function ClassB(sName)

    {                                            this.name = sName;

          this.color = sColor;                       this.sayName=function()

          this.sayColor=function()                  {  alert(this.name); }}

          {

               alert(this.color);

          }

    }

    function ClassC(sColor,sName,sModel){ //classC希望从AB继承

        this.newMethod = ClassA;

        this.newMethod(sColor);

        delete this.newMethod;

        this.newMethod =ClassB;

        this.newMethod(sName);

        delete this.newMethod;

        this.model=sModel;

        this.sayModel = function()

        {

            alert(this.model);

        }

    }

    //call

    var cObj = new ClassC("red","zhang","T40");

    cObj.sayColor();    //output “red”

    cObj.sayName();   //output “zhang”;

    cObj.sayModel(); //output “T40”;

     

     

     

     

    注意:多重继承防止出现父类同名问题

    由于这种方式的流行,ECMAScript的第三版为Function对象加入了两个新方法 Call()apply()

    2Call()方法

    call方法是与经典的对象冒充方法最相似的方法.它的第一个参数用作this的对象,其他参数都直接传递给函数自身.

    eg:

    function sayColor(sprev,snext)

    {

        alert(sprev+this.color+snext); //this说明肯定有对象来调用它

     

    }

    var obj = new Object();

    obj.color = “red”;

    sayColor.call(obj,”The color is ”,”a very nice color”);会把obj对象传给saycolorthis参数

    //output “The color is red ,a very nice color”

    利用call关键字实现继承

    function ClassA(sColor){

          this.color = sColor;

          this.sayColor=function(){

               alert(this.color); }}

    function ClassB(sColor,sName) {

       // this.newMethod=ClassA;

       // this.newMethod(sColor);

       // delete this.newMethod;

    ClassA.call(this,sColor);

    //调用calssA这个函数,传递对象是当前对象本身,并把参数传进去

        this.name = sName;

        this.sayName= function(){

           alert(this.name); }}

    //call

    var objB = new ClassB(“red”,”zhang”);

    objB.sayColor();   //output “red”

     objB.sayName(); //output “zhang”

    apply()方法 

    apply()方法有两个参数,用作this的对象和要传递给函数的参数的数组.

    eg:

    function sayColor(sprev,snext){

        alert(sprev+this.color+snext);}

    var obj = new Object();

    obj.color =“red”;

    sayColor.apply(obj,new Array(“The Color is “,” a very nice color”));第二个参数用数组表示,然后根据数量一一传递给调用函数//output “The color is red ,a very nice color”

    利用apply关键字实现继承

    function ClassA(sColor){

          this.color = sColor;

          this.sayColor=function(){

               alert(this.color);}}}

    function ClassB(sColor,sName){

       // this.newMethod=ClassA;

       // this.newMethod(sColor);

       // delete this.newMethod;

        ClassA.apply(this,new Array(sColor));

       this.name = sName;

        this.sayName= function(){

           alert(this.name); }}

    //call

    var objB = new ClassB(“red”,”zhang”);

    objB.sayColor();   //output “red”

     objB.sayName(); //output “zhang”

    原型链

    利用prototype对象来实现.

    function ClassA(){

    }

    ClassA.prototype.color = “red”;

    ClassA.prototype.sayColor = function(){

         alert(this.color);

    }

    function ClassB(){

    }

    ClassB.prototype = new ClassA //classBclassA继承

    注意,调用ClassA的构造函数时,没有给它传递参数.这在原型链中是标准做法,要确保构造函数没有任何参数.

    :与对象冒充相似,子类的所有属性和方法都必须出现在prototype属性补赋值后,因为在它之前赋值的所有方法都会被删除.

    eg:

    function ClassB(){ //子类不能存在构造函数,否则会被classA替换掉

    }

    ClassB.prototype = new ClassA();

    ClassB.prototype.name = “”;

    ClassB.prototype.sayName = function(){

              alert(this.name);

    }

    //call

    var objA = new ClassA();

    var objB = new ClassB();

    objA.color = "blue";

    objB.color = "yellow";

    objB.name = "zhang";

    objA.sayColor(); //output “blue”

    objB.sayColor(); //output “yellow”;

    objB.sayName(); //output “zhang”

    原型链的弊端在不支持多重继承.记住,原型链会用另一类型的对象重写类的prototype属性

    混合模式

    用构造函数方式定义属性,用原型方式定义方法.这种方式同样适用于继承机制.

    eg:

    //ClassA

    function ClassA(sColor)

    {

        this.color = sColor;

    }

    ClassA.prototype.sayColor = function(){ 

        alert(this.color);

    }

    //ClassB

    function ClassB(sColor,sName){

         ClassA.call(this,sColor);

         this.name = sName;

    }

    ClassB.prototype = new ClassA();

    ClassB.prototype.sayName = function(){//自己的方法sayName

         alert(this.name);

    }

    //call

    var objA = new ClassA(“red”);

    var objB = new ClassB(“blue”,”zhang”);

    objA.sayColor(); //output “red”

    objB.sayColor(); //output “blue” b没有sayColor方法 是从A继承的

    objB.sayName(); //output “zhang”

    一个更实际的例子

         //创建基类(多边形)

       function Polygon(iSides){

           this.sides = iSides;

       }

       Polygon.prototype.getArea=function(){ //原型链方法用来被继承或被重写

                return 0;

       }

       //创建子类(三角形)

       function Triangle(iBase,iHeight){

           Polygon.call(this,3);//通过继承方式设定他3个边

                this.base = iBase;

                this.height = iHeight;

       }

       Triangle.prototype = new Polygon();// 继承弗雷方法

       Triangle.prototype.getArea = function()//重写了计算面积方法

       {

            return this.base*this.height/2;

       }

       //创建子类(四边形)

       function Rectangle(iLength,iWidth){

           Polygon.call(this,4);

                this.length = iLength;

                this.width = iWidth;

       }

       Rectangle.prototype = new Polygon();

       Rectangle.prototype.getArea = function()

       {

           return this.length*this.width;

       }

       //调用

       var triangle = new Triangle(12,4);

       var rectangle = new Rectangle(22,10);

       alert(triangle.sides);   //output “3”

       alert(triangle.getArea()); //output “24”

       alert(rectangle.sides);   //output “4”;

       alert(rectangle.getArea()); //output “220”

    多态

    //Class Parent

       function Person(skin,language)//肤色 语言

       {

          this.skin = skin;

        this.language = language;

       }

       Person.prototype.SayHellow = function(){}

       //中国人--子类

       function China(skin,language,name)

       {

          Person.call(this,skin,language);//继承父类属性

            this.name = name;

        this.SayName = function()

        {

            alert(this.name);

        }

       }

    China.prototype = new Person();//继承父类原型链方法

       China.prototype.SayHellow = function()

       {

           alert("您好");

       }

       //美国人 --子类

       function American(skin,language)

       {

          Person.call(this,skin,language);

       }

       American.prototype = new Person();

       American.prototype.SayHellow = function()

       {

          alert("hellow");

       }

     

    function SayHellow(p)//多态

       {

          p.SayHellow();

       }

    //-->

    </SCRIPT>

    </HEAD>

    <BODY>

    <input type="button" value="中国人的问候" onclick ="SayHellow(new China('黄色','汉语','张三'))"/>&nbsp;<input type="button" value = "美国人的问候" onclick="SayHellow(new American('白色','英语'))"/>

    </BODY>

  • 相关阅读:
    第十周作业
    课堂练习之十字链表
    第三次实验报告
    第九周学习
    队列课下作业
    第七周作业
    第五周作业总结(内含用Junit测试ArrayStack和LinkedStack课堂练习报告)
    20155336 《信息安全系统设计基础》课程总结
    2017-2018-1 20155336 《信息安全系统设计基础》第十四周学习总结
    2017-2018-1 20155336 《信息安全系统设计基础》第十三周学习总结
  • 原文地址:https://www.cnblogs.com/aqbyygyyga/p/2225519.html
Copyright © 2011-2022 走看看