JavaScript物件導向編程 :繼承和重載

來源:互聯網
上載者:User

引用: http://blog.csdn.net/codemon/archive/2004/12/04/204398.aspx
首先我們簡單定義一個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>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.