zoukankan      html  css  js  c++  java
  • 面向对象与原型(三)

    继承:

          继承是面向对象中一个比较核心的概念。其他正统面向对象语言都会用两种方式实现继

    承: 一个是接口实现, 一个是继承。 而ECMAScript只支持继承, 不支持接口实现,而实

    现继承的方式依靠原型链完成。

           function Box(){                       //Box构造
                 this.name='Lee';
           }
           function Desk(){                    //Desk构造
                 this.age=100;
           }
           Desk.prototype=new Box();           //Desc继承了Box, 通过原型, 形成链条
           var desk=new Desk();
           alert(desk.age);
           alert(desk.name);              //得到被继承的属性
           function Table(){               //Table构造
                 this.level='AAAAA';
           }
          Table.prototype=new Desk(); //继续原型链继承
          var table=new Table();
          alert(table.name);               //继承了Box和Desk

                                                     原型链继承图

          在JavaScript里,被继承的函数称为超类型(父类,基类也行,其他语言叫法),继承的函数称为

    子类型(子类,派生类)。继承也有之前问题,比如字面量重写原型会中断关系, 使用引用类型的原型

    ,并且子类型还无法给超类型传递参数。为了解决引用共享和超类型无法传参的问题,我们采用一种

    叫借用构造函数的技术,或者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题。

          function Box(age){

                this.name=['Lee','Jack','Hello']

                this.age=age;

          }

          function Desk(age){

                Box.call(this,age);       //对象冒充,给超类型传参

          }

          var desk = new Desk(200);

          alert(desk.age);

          alert(desk.name);

          desk.name.push('AAA');    //添加的新数据,只给 desk

          alert(desk.name);

          借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需要

    原型链+借用构造函数的模式,这种模式成为组合继承。

          function Box(age) {

                this.name = ['Lee', 'Jack', 'Hello']

                this.age = age;

         }

         Box.prototype.run = function () {

               return this.name + this.age;

         };

         function Desk(age) {

               Box.call(this, age); //对象冒充

         }

         Desk.prototype = new Box(); //原型链继承

         var desk = new Desk(100);

         alert(desk.run());

         还有一种继承模式叫做:原型式继承;这种继承借助原型并基于已有的对象创建新对象,

    同时还不必因此创建自定义类型。

          function obj(o) { //传递一个字面量函数

                function F() {} //创建一个构造函数

                F.prototype = o; //把字面量函数赋值给构造函数的原型

                return new F(); //最终返回出实例化的构造函数

          }

          var box = { //字面量对象

               name : 'Lee',

               arr : ['哥哥','妹妹','姐姐']

           };

           var box1 = obj(box); //传递

           alert(box1.name);

           box1.name = 'Jack';

           alert(box1.name);


           alert(box1.arr);

           box1.arr.push('父母');

           alert(box1.arr);

           var box2 = obj(box); //传递

           alert(box2.name);

           alert(box2.arr); //引用类型共享了

           寄生式继承把原型式+工厂模式结合而来,目的是为了封装创建对象的过程。

           function create(o) { //封装创建过程

                 var f= obj(o);

                 f.run= function () {

                       return this.arr; //同样,会共享引用

                 };

                 return f;

            }

          组合式继承是 JavaScript最常用的继承模式; 但, 组合式继承也有一点小问题, 就是超

    型在使用过程中会被调用两次: 一次是创建子类型的时候, 另一次是在子类型构造函数的部。

          function Box(name) {

                this.name = name;

                this.arr = ['哥哥','妹妹','父母'];

          }

          Box.prototype.run= function() {

                returnthis.name;

          };

          function Desk(name, age) {

                Box.call(this, name); //第二次调用 Box

                this.age = age;

          }

          Desk.prototype = newBox(); //第一次调用 Box

          以上代码是之前的组合继承,那么寄生组合继承,解决了两次调用的问题。

          function obj(o) {

                functionF() {}

                F.prototype= o;

                return new F();

          }

          function create(box,desk){

                var f=obj(box.prototype);

                f.constructor=desk;

                desk.prototype=f;

          }

          function Box(name){

                this.name=name;

                this.arr=['哥哥','妹妹','父母'];

          }

          Box.prototype.run=function(){

                return this.name;

          };

          function Desk(name,age){

                Box.call(this,name);

                this.age=age;

           }

           create(Box,Desk); //通过这里实现继承

           var desk=new Desk('Lee',100);

           desk.arr.push('姐姐');

           alert(desk.arr);

           alert(desk.run()); //只共享了方法

           var desk2=new Desk('Jack',200);

           alert(desk2.arr); //引用问题解决

  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/xbj-2016/p/5127757.html
Copyright © 2011-2022 走看看