JavaScript面向对象编程 :继承和重载

引用: 首先我们简单定义一个OO中关于继承重载定义的子集(不完整定义)   继承 :  子类拥有其父类的方法和属性 重载 :  子类可以重新定义从其父类继承而来的方法   在C++ Class中的继承和重载通过以下简洁方式表现 class CParent   //父类 { public :     string str;   //属性     virtual void  foo() {} //方法 }; class CChild  :public CParent//子类,继承 {   public:    virtaul void foo() { //重载        CParent::foo();//虽然重载了,还可以调用父类的方法,不过在父类的方法中的this却是子类实例的指针哦    } }   在JScript中要实现继承和重载要繁琐得多,要使用prototype 这些东东。那么我们在JScript中有没有简单的方法可以模拟这种效果?经过一番尝试,我想出了一个还算简洁的解决方案,没考虑效率和实用性,给大家参考一下而已。 先说一下使用方法:   <!--模拟继承和重载效果的脚本库--> <SCRIPT LANGUAGE="jscript" src="oop.htm"></SCRIPT> <SCRIPT LANGUAGE="javascript"> <!-- function Parent() {   Class(this);   //使这个类从我们的最顶层的基类派生而来,类似于MFC中的类都从CObject派生呵呵,必须是第一条语句   this.str="Class Parent 的属性值";   this.OutStr=function()  {     window.alert("Class Parent 的方法\t"+this.str);  } } function Son() {   Class(this);  //同上,一定要有   this.Inherit(Parent);   //继承Parent   this.OutStr=function() { //重载Parent的OutStr方法     window.alert("Class Son 的方法\t"+this.str);   }   this.OutStr2=function(){      this.OutStr();//调用重载后的OutStr方法,实际上是Son的OutStr      this.Parent_OutStr();//调用父类Parent的OutStr方法   } } function Grandson() {   Class(this);//同上   this.Inherit(Son);//继承Son   this.str="Class Grandson的属性值"; } var b=new Son(); var c=new Grandson(); b.OutStr();//输出“Class Son的方法  Class Parent 的属性值“,因为Son重载了Paren的OutStr方法但没改变str属性值 c.OutStr();//输出“Class Son的方法  Class Grandson的属性值“,因为Grandson没有重载Son的OutStr方法但改变了str属性值 b.Parent_OutStr(1,"str",window);//调用Parent的OutStr,输出“Class Parent的方法  Class Parent 的属性值“,因为Son没改变str属性值 c.Son_OutStr();//调用Son的OutStr,输出“Class Son的方法  Class Grandson的属性值“,因为Grandson改变了str属性值 c.Son_Parent_OutStr();//调用Parent的OutStr,输出“Class Parent的方法  Class Grandson的属性值“,因为Grandson改变了str属性值 b.OutStr2(); window.alert(c.Tree());//显示c的继承关系图 window.alert(c.MembersMap());//显示c的方法和属性 //--> </SCRIPT> 下面把oop.htm的源代码贴出来大家有兴趣参考一下:)   //这是个脚本文件,请用&lt;SCRIPT LANGUAGE=jscript src="oop.htm"&gt;&lt;/SCRIPT&gt;的方式使用 //<SCRIPT LANGUAGE=javascript> /////////////common function/////////////////////// //取得函数对象的名称,返回字符串 function FunctionName(f) {   if(typeof(f)=="function"){      var pn=new String(f);      var n=pn.indexOf("(",0);      pn=pn.substring(0,n);      pn=pn.replace(/^[ \f\v\t\b\n\r]*/g,"");      pn=pn.replace(/^function/g,"");      pn=pn.replace(/^[ \f\v\t\b\n\r]*/g,"");      pn=pn.replace(/[ \f\v\t\b\n\r]*$/g,"");          return pn;    }    return ""; } /////////////////////////////////////////////////////// //基类 function JSClass() {   //取得类名,返回字符串   this.ClassName=function() {  return FunctionName(this.constructor); }   //指定继承_base类,可以带基类初始化参数如this.Inherit(classBase,param1,param2,param3);   //返回true或false   this.Inherit=function(_base)   {     //检验_base是合法类而且尚未继承_base类     if(typeof(_base)=="function" && !this.IsMyParent(_base))     {       //如此函数是在顶层实例构造(即直接用new产生实例)时调用,isRoot为true       //如此函数是在嵌套派生(即在Inherit中调用基类)时嵌套调用,isRoot为false            var isRoot=(this.constructor==this.Inherit.caller);             this.___super=_base;       //带参数初始化基类       var callString="";       for(i=1;i<arguments.length;i++){           if(i>1) callString+=",";           callString+="arguments["+i+"]";       }       eval("this.___super("+ callString +");");          this.___super=null;              if(isRoot)//如果是顶层实例       {         //{{{如不需要调用IsMyParent和调用基类的方法及工具函数可去掉以下代码         eval("this.___super=new _base(" + callString + ");");//生成基类的实例         Class(this.___super);//保证基类是JSClass的派生类         var pn=this.___super.ClassName();         for(key in this.___super){                    if((!this.IsKeyWord(key)) && typeof(this.___super[key])=="function"){//不要前面带"___"的函数和保留函数                      eval("this."+ pn + "_" + key  + "=this.___super[\"" + key + "\"]");//保存基类方法使之可用this.基类名_基类方法的方式使用                        }         }         var pr=this.Parents();         pr[pn]=this.___super.Parents();//将基类的派生关系数组添加到本类的派生关系数组中         pr.length++;         this.___super=null;         //}}}       }        return true;     }     return false;   }   //tool Method   //判断是否是自己的直接父类,返回true或false   this.IsMyParent=function(obj)   {      var objn="";      var ps=this.Parents();      if(isClass(obj)) objn=obj.ClassName();      else if(typeof(obj)=="function") objn=FunctionName(obj);           if(objn!="") return (typeof(ps[objn])=="object");      else return false;   }     //取派生关系数组,返回Array   this.Parents=function(){      if(!(this.___parents instanceof Array)) this.___parents=new Array();      return this.___parents;   }     //生成类的继承关系图,返回字符串   this.Tree=function()  {   return ClassTree(this);  }     //显示类的结构,返回字符串   this.MembersMap=function()  {    return ClassMembers(this);  }     //取得所有的方法名称,返回一个字符串数组   this.Methods=function()   {     var methodArr=new Array();     for(key in this){        if(typeof(this[key])=="function" && (!this.IsKeyWord(key)))   methodArr.push(key);           }     return methodArr;   }     //取得所有的属性名称,返回一个字符串数组   this.Properties=function()   {     var PropArr=new Array();     for(key in this){        if(typeof(this[key])!="function" && (!this.IsKeyWord(key)))   PropArr.push(key);           }     return PropArr;    }     this.IsKeyWord=function(str)//是否是保留关键字   {      var s=new String("" + str);      if(s.indexOf("___",0)==0) return true;            var o=new JSClass();      if(typeof(o[s])=="function") return true      return false;   } } //////////tools funciton//////////////////////// //使一个类是JSClass的派生类 function Class(o) {   if(typeof(o)=="object" && typeof(o.constructor)=="function" )  {      o.___class=JSClass;      o.___class();      return true;   }   return false; }   //判断一个类是否JSClass的派生类 function isClass(o) {   if(typeof(o)=="object" && typeof(o.constructor)=="function" ) {      if(typeof(o.___class)=="function" && o.___class===JSClass)   return true;   }   return false; }   //生成JSClass类的继承关系图,返回字符串 function ClassTree(jscObject) {   var outputStr="";   function ___dump(objName,parentList,preString,isLast,InheritLevel)   {     var i=0;       if(InheritLevel>32) outputStr+=preString+"__"+objName+" ......\n";     else outputStr+=preString+"__"+objName+"\n";         if(parentList.length>0)     {         var newPreString=new String(preString);        if(isLast) newPreString=newPreString.replace(/[|]$/i,"");        newPreString+="    |";        i=0;        for(key in parentList) {                  ___dump(key,parentList[key],newPreString,(i==parentList.length-1),InheritLevel+1);          i++;        }          }   }     if(isClass(jscObject))  ___dump(jscObject.ClassName(),jscObject.Parents(),"",false,0);   else outputStr="NOT_JSCLASS_OBJECT";    return outputStr; }   //显示JSClass类的结构,,返回字符串 function ClassMembers(jscObject) {   var outputStr="";     if(isClass(jscObject))   {      outputStr+="class " + jscObject.ClassName() + "\n";      var m=jscObject.Methods();      var p=jscObject.Properties();      outputStr+="\n    Methods\n";      for(key in m) {   outputStr+="      |__ "+m[key]+"\n";    }      outputStr+="\n    Properties\n";      for(key in p) {   outputStr+="      |__ "+p[key]+"\n";    }   }   else outputStr="NOT_JSCLASS_OBJECT";    return outputStr; } //</SCRIPT>
27人参与, 0条评论 登录后显示评论回复

你需要登录后才能评论 登录/ 注册