• Ext OOP基础


    第三章:Ext OOP基础
    一、javascript类的定义
        在javascript中,通过创建一个构造函数来定义一个类,然后通过prototype来扩展类的功能。假设我们定义一个螃蟹类:
    Crab = function(){
         this.legs = 10;
    }
     
    Crab.prototype = {
         say: function(){
                alert("我是一只螃蟹,我有" + this.legs + "只脚,横行霸道是我的天性");
         }
    };
    //测试
    var crab = new Crab();
    alert(crab.legs);
    crab.say();
           prototype是javascript一个非常重要的功能,能动态的为对象添加任何新的方法。Extjs就是基于prototype实现的OOP机制。
     
    二、Extjs命名空间的定义
        命名空间(namespace)类似于java中的包,用来对工程中的类进行有效管理。命名空间的层次结构使用“.”来划分。Ext通过namespace()方法创建命名空间。
        语法:Ext.namespace(“命名空间”)
        示例:Ext.namespace("com.aptech");
    三、Extjs OOP
        在Extjs中创建类和javascript有些不同,我们会使用他封装好的东西,而不全是基于javascript语法。站在巨人的肩膀上,确实有些高处不胜寒。所以,深刻了解javascript基础对于日后的拓深十分必要,相信我吧。
     
        我们通常会基于命名空间创建新类,按照java的设计思想,会有封装、继承和多态Extjs也不例外,而且Extjs为OOP做了很多基础工作,使用起来非常模式化。一个类至少应该有private和public成员,且可以派生出子类,并能重写父类的方法。那么,让我们来看看Extjs是如何做到的。
    Ext.namespace("com.aptech");
     
    com.aptech.First = function(){
         //私有成员
         var kiss = "中华人民共和国";
         //私有方法
     
         //公有方法
         return {
                //公有成员
                init: function(){
                       alert("init");
                       alert(kiss);
                },
                //公有成员
                method: function(){
                       alert("method");
                }
         };
    };
       
        我们定义了一个类First,这实在是一个没有任何业务意义的类,只是为了说明方便。First位于com.aptech命名空间中,有一个私有成员kiss,并且向外部暴露了两个方法init()和method()。其实,在function和return之间定义的成员全总是private,而在ruturn内部定义的成员全部是public,如果大家的javascipt基础扎实的话,这段代码并不难理解,我们定义了一个匿名构造函数,函数中的变量是局部变量,外部无法访问,返回一个对象,对象是以json格式定义的,该对象中定义的方法自然可以访问了。
     
           javascipt本身不支持继承,但是我们可以模拟。继承说穿了就是子类将父类的成员据为已有,专业点就是“成员复制”,即可以复制成员变量,也可以复制成员方法。我们定义下面的方法完成此功能:
    var extend = function(child, father){
         child.prototype = father.prototype;
    }
        现在,我们定义一个螃蟹的子类——蟹将,螃蟹成精变成了人,由原来的10只脚变成2只脚,但狗改不了吃屎,行为不会改变,依旧横行霸道。
    GenCrab = function(){this.legs = 2;};
    extend(GenCrab, Crab);
    var gc = new GenCrab();
    gc.say();
        就这样,一个新类产生了。不过,在Extjs中有更加优雅的做法。
     
        我们定义一个类Second,继承自First,看看Extjs是如何做的。
    //创建子类
    com.aptech.Second = function(){
         com.aptech.Second.superclass.constructor.apply(this);//调用父类构造方法
    }
    //com.aptech.Second子类继承自父类com.aptech.First
    Ext.extend(com.aptech.Second, com.aptech.First, {
         //新方法
         fun: function(i){
                return i * i * i;
         },
         //重写的方法
         method: function(){
                alert("Second::method")
         }
    });
     
    //测试
    var second = new com.aptech.Second();
    alert(second.fun(5));
    second.method();
        哈哈,简直太优雅了,不仅可以添加新方法,还可以重写父类的方法(话外音:这不是多态的表现形式吗?)。这一切都是由Ext.extend()搞定的,这个方法有点复杂,但他的实现原理是相同的。
    四、配置(config)选项
        在Extjs中,初始化对象时,大量使用了config这个参数。不要恐惧,只是一个json对象而已,不过,config为Extjs立下了不少汗马功劳。
       
        假设定义了一个学生类(Student),有姓名和性别两个属性,并且通过构造函数为属性初始化:
    Student = function(name, sex){
         this.name = name;
         this.sex = sex;
    }
     
    //测试
    var student = new Student("李赞红", "男");
    alert("姓名:" + student.name + "\r\n性别:" + student.sex);
        这个一定看得懂,如果看不懂,我只能表示深深的遗憾了,您不适合地球,回你的老本营火星去吧。
       
        如果用json对象作为构造函数的参数呢?
    Student = function(config){
         this.name = config.name;
         this.sex = config.sex;
    }
     
    //测试
    var student = new Student({name: "李赞红", sex: "男"});
    alert("姓名:" + student.name + "\r\n性别:" + student.sex);
        嘿,果然万变不离其宗啊。换汤不换药的把戏骗不了咱们。但是,等等,请等等,如果类的成员特别多,十个,二十个,一百个,赋值语句岂不是很多很繁琐?你能想到这一点实在太聪明了,不过,Jack更聪明,他早想到了,于是有了下面的代码:
    Student = function(config){
         Ext.apply(this, config);
    }  
     
    //测试
    var student = new Student({name: "李赞红", sex: "男"});
    alert("姓名:" + student.name + "\r\n性别:" + student.sex);
           Ext定义了一个名叫apply()的方法,作用是将第二个参数的成员赋给第一个参数。现在,不管config中有多少个成员都没问题了。
    五、Ext.apply()Ext.applyIf()
        前面我们知道了Ext.apply(obj, config)方法的作用,还有另一个方法applyIf(obj, config),从名字上看得出来,applyIf()需要满足某种条件,实在是太棒了,这么复杂的问题都没逃过你的法眼。
       
        事先预告一下这两个方法的区别,然后再通过例子来说明:apply会将config和obj参数的同名属性值覆盖,并且将config其他属性添加到obj中;applyIf不会将config和obj参数的同名属性覆盖,只将config其他属性添加到obj中。也就是说,obj没有而config中有的属性最终都会复制到obj中,不同的是相同属性值是否会被覆盖的问题。
        例子能说明一切问题。
    Student = function(config){
         this.name = "张海军";
         this.sex = "男";
         Ext.apply(this, config);
    }
     
    //测试
    var student = new Student({name: "李赞红", sex: "男", birthday: new Date()});
    alert("姓名:" + student.name + "\r\n性别:" + student.sex + "\r\n生日:" + student.birthday);
        从下面结果看出,属性name和sex均被覆盖,且添加了新成员birthday。
    姓名:李赞红
    性别:男
    生日:Fri May 01 2009 07:59:39 GMT+0800
       
    Student = function(config){
         this.name = "张海军";
         this.sex = "男";
         Ext.applyIf(this, config);
    }
     
    //测试
    var student = new Student({name: "李赞红", sex: "男", birthday: new Date()});
    alert("姓名:" + student.name + "\r\n性别:" + student.sex + "\r\n生日:" + student.birthday);
        结果如下:
    姓名:张海军
    性别:男
    生日:Fri May 01 2009 08:02:33 GMT+0800
        哈,“张海军”终于没被“李赞红”替换了。
    六、小结
        讲了这么多,尽是些和Ext不沾边的事,是不是有点失望?
       
        但是,我用人格担保我是个不啰嗦的人,了解我的学生肯定知道。这一章的内容是Extjs的基础,是我们能看懂源代码的保证。不然,看到Jack的代码,你以为自己进入了迷宫,或者Jack故意要把我们打入冷宫。
     
        虽然是基础,却是相对的,因为就是这寥寥几行代码,蕴含了丰富的设计哲学,细细体会,才知其味。
  • 相关阅读:
    Matrix Power Series
    Recursive sequence HDU5950
    P2151 [SDOI2009]HH去散步
    P4273 [NOI2004] 降雨量
    P1034 [NOIP2002 提高组] 矩形覆盖
    P1027 [NOIP2001 提高组] Car 的旅行路线
    Win10使用Dism++离线安装.Net3.5
    WPF之模板
    WPF之资源
    WPF之命令
  • 原文地址:https://www.cnblogs.com/timy/p/1751090.html
Copyright © 2020-2023  润新知