javascript 面向对象编程基础 多态


Posted in Javascript onAugust 21, 2009

Javascript已经可以模拟出面向对象的封装和继承特性,但是不幸的是Javascript对多态特性的支持非常弱!其它面向对象语言的多态一般都由方法重载和虚方法来实现多态,Javascript也通过这两种途径来实现!

重载:由于Javascript是弱类型的语言,而且又支持可变参数,当我们定义重载方法的时候,解释器无法通过参数类型和参数个数来区分不同的重载方法,因此方法重载是不被支持的!当先后定义了同名的方法的时候,后定义的方法会覆盖先定义的方法!

既然解释器无法分辨重载方法,那就手动区分不同的方法:

var MyClass=function(){ 
var AddNum=function(a,b){ 
return a+b; 
} 
var AddString=function(a,b){ 
return "I am here"+a+b; 
} 
this.Add=function(a,b){ 
if(typeof(a)=="number") 
return AddNum(a,b); 
else 
return AddString(a,b); 
} 
} 
var MyObj = new MyClass(); 
var X = MyObj.Add(5,6); 
var Y = MyObj.Add("A","FFFFFF"); 
alert(X); //结果:11 
alert(Y); //结果:I am hereAFFFFFF

虚方法:
function BaseClass(){ 
this.Hello=function(){ 
return this.Say(); 
} 
} 
function MyClassA(){ 
this.Say=function(){ 
return "Hello"; 
} 
} 
function MyClassB(){ 
this.Say=function(){ 
return "This is MyClassB"; 
} 
} 
MyClassA.prototype = new BaseClass(); 
MyClassB.prototype = new BaseClass(); 
var ObjA = new MyClassA(); 
var XX = ObjA.Hello(); 
alert(XX); //结果:Hello 
var ObjB = new MyClassB(); 
var YY = ObjB.Hello(); 
alert(YY); //结果:This is MyClassB

由于Javascript解释执行的特性,因此可以再基类中调用将要在派生类中定义的方法,那么这个基类方法就相当于虚方法,可以实现模拟多态!
js的重载和重写(覆写):
重载的意思是,“同一个名字的函数(注意这里包括函数)或方法可以有多个实现,它们依靠参数的类型和(或)参数的个数来区分识别”。而重写(覆盖)的意思是,“子类中可以定义与父类中同名,并且参数类型和个数也相同的方法,这些方法的定义后,在子类的实例化对象中,父类中继承的这些同名方法将被隐藏”。重载的英文是overload,覆盖的英文是override。好了,概念介绍到这里,你猜到我要说什么了吗?嘿嘿,Code is cheap.看重载代码:
// 通过函数的arguments属性实现重载 
function add() { 
var sum = 0 ; 
for ( var i = 0 ; i < arguments.length; i ++ ) { 
sum += arguments[i]; 
} 
return sum; 
} 
function test() { 
alert(add()); 
alert(add( 1 , 2 )); 
alert(add( 1 , 2 , 3 )); 
}

通过代码运行结果,这样就实现了任意多个参数加法函数的重载了。当然,你还可以在函数中通过 instanceof 或者 constructor 来判断每个参数的类型,来决定后面执行什么操作,实现更为复杂的函数或方法重载。总之,javascript 的重载,是在函数中由用户自己通过操作 arguments 这个属性来实现的。关于arguments的特性,前面我已经做了简单介绍,参考拙文:http://blog.csdn.net/zhanglingdll_39/archive/2009/08/20/4465670.aspx 。
下面重点理解js重写的实现:
// 为类添加静态方法inherit表示继承于某类
Function.prototype.inherit = function (baseClass) {
for ( var p in baseClass.prototype) {
this .prototype[p] = baseClass.prototype[p];
}
}
// js实现重写
function parentClass() { // 父类
}
parentClass.prototype.method = function () {
alert( " parentClass method " );
}
function subClass() { // 子类
}
//
下面这一句和subClass.prototype = new parentClass();等价 
subClass.inherit(parentClass); 
// subClass.prototype.method = function() { // 子类重写了父类的方法 -- 去掉注释运行试试看 
// alert("subClass method"); 
// } 
function test() { 
var obj = new subClass(); 
obj.method(); 
} 
这样,子类中定义的method 就覆盖了从父类中继承来的method 方法了。这是你可能会问,如何在子类中调用父类的method方法呢?好的,看实现如下: 
// 为类添加静态方法inherit表示继承于某类 
Function.prototype.inherit = function (baseClass) { 
for ( var p in baseClass.prototype) { 
this .prototype[p] = baseClass.prototype[p]; 
} 
} 
/* 参考文章:http://menjoy.javaeye.com/blog/127847 */ 
// js实现重写 
function parentClass() { 
this .method = function () { 
alert( " parentClass method " ); 
} 
} 
function subClass() { 
var method = this .method; 
this .method = function () { 
method.call( this ); 
alert( " subClass method " ); 
} 
} 
subClass.prototype = new parentClass(); 
// subClass.inherit(parentClass); //这一句貌似和上一句subClass.prototype = new parentClass();等价,其实呢????(注释上一行,运行这一行看看) 
subClass.prototype.constructor = subClass; 
function test() { 
var obj = new subClass(); 
obj.method(); 
}

好了,关于多态的介绍就到这里。js面向对象编程犹如浩瀚海洋广阔无边,我这三篇参考别人的文章写出来的js面向对象基础只能当作入门者学习的参考。学无止境,参考了网上几篇老大们的牛文,深知自身技术的浅薄,对于已经超越了解阶段的读者,还是看看园子里高人的技术文章吧。我这里要先拜谢园子里的高人了。
Javascript 相关文章推荐
flash javascript之间的通讯方法小结
Dec 20 Javascript
jquery封装的对话框简单实现
Jul 21 Javascript
使用js对select动态添加和删除OPTION示例代码
Aug 12 Javascript
json数据与字符串的相互转化示例
Sep 18 Javascript
javascript实现切换td中的值
Dec 05 Javascript
超级简单的jquery操作表格方法
Dec 15 Javascript
浅谈jQuery构造函数分析
May 11 Javascript
小程序实现带年月选取效果的日历
Jun 27 Javascript
vue-router命名视图的使用讲解
Jan 19 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
Nov 07 Javascript
浅谈vue中resetFields()使用注意事项
Aug 12 Javascript
基于Cesium绘制抛物弧线
Nov 18 Javascript
javascript 面向对象编程基础:继承
Aug 21 #Javascript
javascript 面向对象编程基础:封装
Aug 21 #Javascript
javascript arguments 传递给函数的隐含参数
Aug 21 #Javascript
javascript 自定义事件初探
Aug 21 #Javascript
IE 下的只读 innerHTML
Aug 21 #Javascript
JS 控制CSS样式表
Aug 20 #Javascript
JS获取父节点方法
Aug 20 #Javascript
You might like
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
2010/05/10 PHP
PHP5中使用PDO连接数据库的方法
2010/08/01 PHP
php文件操作小结(删除指定文件/获取文件夹下的文件名/读取文件夹下图片名)
2016/05/09 PHP
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
Eval and new funciton not the same thing
2012/12/27 Javascript
javascript实现控制浏览器全屏
2015/03/30 Javascript
全面了解JavaScript的数据类型转换
2016/07/01 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
2017/01/18 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
vue.js+element-ui动态配置菜单的实例
2018/09/07 Javascript
微信小程序实现单选选项卡切换效果
2020/06/19 Javascript
js仿淘宝放大镜效果
2020/12/28 Javascript
[37:35]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第二局
2016/02/25 DOTA
rhythmbox中文名乱码问题解决方法
2008/09/06 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
用pytorch的nn.Module构造简单全链接层实例
2020/01/14 Python
如何基于Python pygame实现动画跑马灯
2020/11/18 Python
canvas学习笔记之绘制简单路径
2019/01/28 HTML / CSS
Nike香港官网:Nike HK
2019/03/23 全球购物
会计工作心得体会
2014/01/13 职场文书
给全校老师的建议书
2014/03/13 职场文书
班主任评语大全
2014/04/26 职场文书
大学班级学风建设方案
2014/05/01 职场文书
我爱幼儿园演讲稿
2014/09/11 职场文书
2014年教育工作总结
2014/11/26 职场文书
2014年会计主管工作总结
2014/12/20 职场文书
初中差生评语
2014/12/29 职场文书
公司人事任命通知
2015/04/20 职场文书
2016大学军训心得体会
2016/01/11 职场文书
2016教师读书思廉心得体会
2016/01/23 职场文书
农村房屋租赁合同(范本)
2019/07/23 职场文书
python之django路由和视图案例教程
2021/07/26 Python
CSS控制继承中的height能变为可继承吗
2022/06/10 HTML / CSS
Vue router配置与使用分析讲解
2022/12/24 Vue.js