JavaScript继承与聚合实例详解
本文实例讲述了javascript继承与聚合。分享给大家供大家参考,具体如下:
一、继承
第一种方式:类与被继承类直接耦合度高
1. 首先,准备一个可以被继承的类(父类),例如
//创建一个人员类 function person(name) {//现在person里面的域是由person里面的 来this来控制的 this.name=name; }
2. 然后,有个需要继承父类的子类
function teacher(name,books) { person.call(this,name);//相当于java中的super函数 在new teacher时将person的name初始化 this.books=books; }
说明一下:
(1)call方法可以将一个函数的对象上下文从初始化变成由this来决定一个类去控制另一个类
(2)teacher类去控制 person类 用teacher域里面的 this来控制person域里面的 this
(3)调用 perosn的构造函数,因为perosn没有用 new 所以是个空对象(模板) 显示调用call方法,可以初始化 person
3. 最后,实现继承
(步骤1)先继承
teacher.prototype=new person(); teacher.prototype.constructor=teacher;//确保继承后任然是teacher自己的构造函数
(步骤2)为子类扩展一些方法,用于访问从父类继承的内容
teacher.prototype.getbook=function () { return this.name+" "+this.books; }
(步骤3)使用已经继承好的类
var jim=new teacher("jim","javascript"); alert(jim.getbook())
总结:此种方法是直接在子类中显示调用父类,耦合度高,复用性差。
第二种方式,使用封装,完成程序中所用继承操作
1. 首先,准备一个可以被继承的类(父类),例如
//创建一个人员类 function person(name) {//现在person里面的域由person里面的来this来控制的 this.name=name; }
2. 创建extend函数为了程序中所有的继承操作(最重要的地方)
/*创建extend函数为了程序中所有的继承操作*/ //subclass:子类 superclass:超类(2) function extend(subclass,superclass) { //1,使子类原型属性等于父类的原型属性 //初始化一个中间空对象,目的是为了转换主父关系 var f = function () {}; f.prototype = superclass.prototype; //2, 让子类继承f subclass.prototype = new f(); subclass.prototype.constructor = subclass; //3,为子类增加属性 superclass ==》原型链的引用 subclass.superclass = superclass.prototype; //4,增加一个保险,就算你的原型类是超类(object)那么也要把你的构造函数级别降下来 【说明一些:这里只是其中一个简单的保险,其余情况后续增加。。。】 if (superclass.prototype.constructor == object.prototype.constructor) { superclass.prototype.constructor = superclass; } }
3. 有一个需要继承其他类的子类
function author(name,books) { author.superclass.constructor.call(this,name);//没有直接写父类,降低了耦合度 //person.call(this,name) 直接写person代表其构造函数 this.books=books; this.getbooks=function () { return this.name+" "+this.books ; } }
4. 最后,实现继承
//继承 extend(author,person);//(子类,父类)
5. 使用已经继承好的类
var peter=new author("peter","javascript"); alert(peter.getbooks());
方式二图解为:
这里可能会有一个疑问就是为啥要使用中间类???
这里假如没有中间类的话,我们在实例化子类时就需要为父类传递一些相应的参数,这样的话,该句代码
author.superclass.constructor.call(this,name);
就不能放在子类(author)中,而是需要放入到extend中,这样的话代码的通用性就很低,故此需要使用中间类。
二、聚合
使用聚合的原因,有的时候不需要严格的继承,我们真正需要的是一个类(或几个类)中的一些函数。故此我们可以使用聚合 也就是使用 掺元类
对于聚合有两种情况
第一种是聚合到 var a={}空类或者不是用function声明的类中
1. 首先,需要一个合适的可以被聚合的类(给体),此时需要在本类的内部进行扩展属性,方法
var json={//写到类的内部 tojsonstring:function () { var output=[]; for(key in this){//this代表那个调用,就指向那个一个对象 output.push(key+"---->"+this[key]); } return output; } };
2. 制作一个聚合函数(最重要)
/*聚合函数 receivingclass:接受聚合内容的类 givingclass:被聚合的目标类 * */ function mixin(receivingclass,givingclass){ for(methodname in givingclass){ if(!receivingclass.__proto__[methodname]){//判断当前原型中是否含有即将要被聚合的方法,若没有则聚合进来 receivingclass.__proto__[methodname]=givingclass[methodname];//直接获得类中的方法,因为方法是直接写在方法内部的。 } } }
3. 接受聚合的类(受体)
var get={name:"text",age:20};
4. 实现将json类的方法聚合到类get中
mixin(get,json);//(受体,给体)
5. 使用get类中聚合的方法
document.write(get.tojsonstring().join(","));
第二种是聚合用function声明的类中
var a=function(){}
1. 首先,需要一个合适的可以被聚合的类(给体),此时需要在本类的原型对象上进行扩展属性,方法
var json={}; json.prototype={//写到类的原型对象上 tojsonstring:function () { var output=[]; for(key in this){//this代表那个调用,就指向那个一个对象 output.push(key+"---->"+this[key]); } return output; } }
2. 制作一个聚合函数
(2)制作聚合函数(receivingclass中聚合givingclass中的属性,或者方法)
function mixin(receivingclass,givingclass) { for(methodname in givingclass.prototype){ if(!receivingclass.prototype[methodname]){//判断当前原型中是否含有即将要被聚合的方法,若没有则聚合进来 receivingclass.prototype[methodname]=givingclass.prototype[methodname]; } } }
3. 接受 聚合的类(受体)
var o=function () { this.name="聚合"; this.age=19; }
4. 实现json类到o类的聚合(将json类中的方法聚合到o类中)
mixin(o,json);//(受体,给体)
5. 使用o类中聚合而来的方法
var useo=new o(); document.write(useo.tojsonstring().join(","));
第二种图解理解为:
该方式属于类o上一层的聚合。
更多关于javascript相关内容还可查看本站专题:《javascript面向对象入门教程》、《javascript错误与调试技巧总结》、《javascript数据结构与算法技巧总结》、《javascript遍历算法与技巧总结》及《javascript数学运算用法总结》
希望本文所述对大家javascript程序设计有所帮助。