基于“甘露模型”的多重继承和接口实现,附带“准”桥接模式的验证

转自:博客园梁逸晨的IT专栏 http://www.cnblogs.com/kvspas/archive/2008/02/28/1085136.html 看了李战师兄的《悟透javascript》,受益非浅。基于甘露模型的基础上,我稍微做了些修改,支持了多重继承和接口(浏览器、ASP-jscript和jscript.net三种环境下调试通过)。 关于多重继承,也许会有些朋友存在意见,而我的观点是,用与不用和用得好用得坏,是人的问题,而不是编译器的问题。 在接口的继承上,函数Class会自动查找当前类是否已经实现了接口的方法,如果没有实现,则会抛出错误,终止执行,这也相当于尽量接近了C#的: class 某某某:接口1,接口2,接口3 { //------------------------ } 在最后面,通过一个桥接模式,来验证这些功能。 难免会有疏漏,还请大家指明。 再次感谢李战师兄的点化。 var Function = {}; Function.Amethod = null; function Class() //创建类的函数,用于声明类及继承关系 { var args = Class.arguments; //获取参数集合 function class_() //创建类的临时函数壳 { this.Type = args[0]; //我们给每一个类约定一个Type属性,引用其继承的类 try { for (var i = 0; i < args.length; i++) { for (var member in args[i]) { if (args[i][member] != Function.Amethod) { this[member] = args[i][member]; //复制类的全部定义到当前创建的类 } else { //如果检测到这是一个虚函数,则判断继承链中存在接口。 //检测当前类是否已经实现了接口的方法 if (!args[args.length - 1][member]) { throw ("错误信息:未实现" + member); return false; } } } } } catch (err) { /**//* Response.Write(err); //在asp和asp.net中 Response.End(); */ window.alert(err); //在浏览器中 } }; return new class_(); } var Interface = function(method) { function temp() { for (var a in method) { this[a] = Function.Amethod; } } return new temp(); } function New(aClass, aParams) //创建对象的函数,用于任意类的对象创建 { function new_() //创建对象的临时函数壳 { this.Type = aClass; //我们也给每一个对象约定一个Type属性,据此可以访问到对象所属的类 if (aClass.Create) aClass.Create.apply(this, aParams); //我们约定所有类的构造函数都叫Create,这和DELPHI比较相似 }; new_.prototype = aClass; return new new_(); } 接口应用在浏览器客户端的执行测试 /* ------------------- 甘露滋养完毕,下面是 桥接模式,下面的测试仅限于浏览器环境中 -------------------- ------------------- 测试环境要求HTML文档中必须有一个id值为"re"的div标签 ---------------------------- */ var AbstractCar = Interface({ run: null }); var AbstractRoad = Interface({ car: null, run: null }); var Car = Class ( AbstractCar, { run: function() { document.getElementById("re").innerHTML += "Car "; } } ); var Bus = Class ( AbstractCar, { run: function() { document.getElementById("re").innerHTML += "Bus "; } } ); var SpeedWay = Class ( AbstractRoad, { car: {}, run: function() { this.car.run(); document.getElementById("re").innerHTML += "in the SpeedWay"; } } ); var Street = Class ( AbstractRoad, { car: {}, run: function() { this.car.run(); document.getElementById("re").innerHTML += "in the Street"; } } ); window.onload = function() { var Road1 = New(Street); //桥接模式特征:变化点1 Road1.car = New(Bus); //变化点2 Road1.run(); document.getElementById("re").innerHTML += "
"; var Road2 = New(SpeedWay); //桥接模式特征:变化点1 Road2.car = New(Car); //变化点2 Road2.run(); } 在下面的服务器端应用执行时,需要把上面的甘露模型代码中的window.alert(err);一句注释掉,并开启原来已经注释的Response.Write 接口应用在服务器端的执行测试(ASP和ASP.NET) var AbstractCar = Interface({ run: null });//抽象车 var AbstractRoad = Interface({ car: null, run: null });//抽象路 var Car = Class //实体小汽车,继承于抽象车 ( AbstractCar, { run: function() { Response.Write("Car "); } } ); var Bus = Class //实体公交车,继承于抽象车 ( AbstractCar, { run: function() { Response.Write("Bus "); } } ); var SpeedWay = Class ( AbstractRoad, { car: {}, run: function() { this.car.run(); Response.Write("in the SpeedWay"); } } ); var Street = Class ( AbstractRoad, { car: {}, run: function() { this.car.run(); Response.Write("in the Street"); } } ); var Road1 = New(Street); //桥接模式特征:变化点1 Road1.car = New(Bus); //变化点2 Road1.run(); Response.Write("
"); var Road2 = New(SpeedWay); //桥接模式特征:变化点1 Road2.car = New(Car); //变化点2 Road2.run(); 通过以上的两个例子,虽然我们在代码层面和执行层面上都实现了接口,但是回过头来说,Javascript语言本身就属于动态语言,它的变量声明是可以指向任何对象的,var a = 1; var a = "text"; var a = new Array(); 都是正确的,这也就说明了javascript本身就内置了“多态性”,似乎我们再构造一个接口就显得有些多余了。 其实不然,接口在强类型语言中除了在多态性应用上起到至关作用外,还有另一个特征:“你必须实现某某某方法!”,这在大型程序的开发上显得至关重要。或许我们会说javascript谈不上开发大型程序,但是要注意到,哪怕是一个小组件,连续不断地升级和修改都是常见的,两个月前写的代码,很难保证两个月后自己还能看得懂多少。此时如果在代码中出现接口继承,多多少少可以起到一个提示的作用:“想起来了,原来是这么回事。”,另一种情况:在其它程序员基于你的组件库平台之上开发新的应用时,你也只需要告诉他:“你继承这个接口就行了,它会自动帮你验证的”。 至于多重继承,办法很简单,不再多说了,给个例子: var p1 = Class({pp1:"pp1"}); var p2 = Class({pp2:"pp2"}); var p3 = Class({pp3:"pp3"}); var xxx = Class(p1,p2,p3,{/* 当前类主体定义 */});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值