zoukankan      html  css  js  c++  java
  • ASP.NET AJAX(6)__Microsoft AJAX Library中的面向对象类型系统

    如果我们可以合理的使用面向对象编程,我们可以提高代码的复用性和可维护性,这里强调的是合理的使用,有了面向对象类型系统,就可以使用一些成熟的设计方式

    命名空间

    • 合理的组织大量的类型,使开发人员能够方便的找到他们所需要的类型
    • 可重复注册命名空间,每个独立的脚本模块前都要注册命名空间以保证命名空间存在

    • 定义构造函数
    • 定义成员(方法、属性、事件)
    • 注册类

    类——构造函数

    • 类的构造函数即为function定义
    • 通常用于初始化域变量
    • 自由成员使用下划线开头(形式上的封装)

    类——定义方法

    • 使用prototype定义
    • MyNamespace.MyClass.prototype={method1:function{},method2:function()}

    类——定义属性

    • Microsoft AJAX Library的面向对象类型系统将get_xxx和set_xxx开头的方法认做属性(一种约定)
    • 避免定义只写属性,使用某个方法替代

    类——注册类

    1. Tye.registerNamespace("MyNamespace");
    2. MyNamespace.MyClass=function(parm1,…){…}
    3. MyNamespace.MyClass.prototype={…}
    4. MyNamespace.MyClass.registerClass("MyNamespace.MyClass");
    一个定义以及使用类的示例

    创建一个js文件

    我们可以在js文件一开始,写上/// <reference name="MicrosoftAjax.js" />这样一段代码,就可以在VS里得到很多关于Microsoft AJAX Library的代码提示

    /// <reference name="MicrosoftAjax.js" />
    
    Type.registerNamespace("MyNamespace");//注册一个命名空间
    MyNamespace.Employee = function(name) {//定义一个构造函数
        this._name = name ? name : "Anonymous";//初始化域变量
        this._year = 0; //初始化域变量
    }
    
    MyNamespace.Employee.prototype =//定义类成员
    {
        get_name: function() {//定义属性
            return this._name;
        },//注意都是用逗号分割的
        get_year: function() {//定义属性
            return this._year;
        },
        set_year: function(value) {//定义属性
            this._year = value;
        },
    
        calculateSalary: function() {//定义一个方法
            return this._year * 1000;
           // throw Error.notImplemented();
        },
    
        getDescription: function() {//定义一个方法
            return String.format("{0} gets {1} yuan per month", this._name, this.calculateSalary());
        }
    }
    MyNamespace.Employee.registerClass("MyNamespace.Employee"); //注册类
     

    这样,我们就定义了一个简单的Employee类

    创建一个aspx页面,并使用我们定义好的Employee类

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="s" runat="server">
                <Scripts>
                    <asp:ScriptReference Path="~/Demo05/Employee.js" />
                </Scripts>
            </asp:ScriptManager>
            <div id="info">
            </div>
    
            <script language="javascript" type="text/javascript">
                   function display(text) {
                       document.getElementById("info").innerHTML+=text+"<br/>";
                   }
    
                   var xiaoyaojian = new MyNamespace.Employee("xiaoyaojian");
                   xiaoyaojian.set_year(4);
                   display(xiaoyaojian.getDescription());
            </script>
        </form>   
    </body>
    </html>

    调试,出结果,用法很简单,和c#类相同

    类——抽象类

    • 包含抽象方法的类即为抽象类
    • MyNamespace.MyClass.prototype{this._mymethod=function{throw Error.notImplemented();}}//包含抽象方法

    类——继承

    • 调用父类的构造函数
    • 有父类的类必须调用父类的构造函数,否则会丢失继承效果(不和c#相同,c#自动调用)
    • MyNamespace.MyClass=function(){MyNamespace.MyClass.initializeBase(this,[param1,…])}
    • 注册时候提供父类
    • 可以直接以普通方式实现父类的抽象成员
    • toString方法无法被继承

    类——调用父类方法

    • MyNamespace.MyClass.prototype={myMethod:function(param1,…){MyNamesapce.MyClass.callBaseMethod(this,"meMethod",[param1,…])}}
    一个示例

    修改上面的Employee.js

    /// <reference name="MicrosoftAjax.js" />
    
    Type.registerNamespace("MyNamespace");//注册一个命名空间
    
    MyNamespace.Employee = function(name) {//定义一个构造函数
        this._name = name ? name : "Anonymous";//初始化域变量
        this._year = 0; //初始化域变量
    }
    
    MyNamespace.Employee.prototype =//定义类成员
    {
        get_name: function() {//定义属性
            return this._name;
        },//注意都是用逗号分割的
        get_year: function() {//定义属性
            return this._year;
        },
        set_year: function(value) {//定义属性
            this._year = value;
        },
    
        calculateSalary: function() {//定义一个方法
            //return this._year * 1000;
            throw Error.notImplemented();//抛出异常,这个方法是抽象方法,说明这个类是抽象类
        },
    
        getDescription: function() {//定义一个方法
            return String.format("{0} gets {1} yuan per month", this._name, this.calculateSalary());
        }
    }
    MyNamespace.Employee.registerClass("MyNamespace.Employee"); //注册类
    //MyNamespace.Employee.registerClass("MyNamespace.Employee", null, MyNamespace.IEmployee);//注册类
    
    
    MyNamespace.Intern = function(name) {
        MyNamespace.Intern.initializeBase(this, [name]);//调用父类构造函数
    }
    
    MyNamespace.Intern.prototype =
    {
        calculateSalary: function() {
            return 2000;
    
        },
        getDescription: function() {
            var description = MyNamespace.Intern.callBaseMethod(this, "getDescription");//调用父类方法
               
            return description + ",What a poor intern!";
    
        }
    }
    
    MyNamespace.Intern.registerClass("MyNamespace.Intern", MyNamespace.Employee); //注册这个类,继承MyNamespace.Employee
    
    
    MyNamespace.Vendor = function(name) {
        MyNamespace.Vendor.initializeBase(this, [name]);
    }
    
    MyNamespace.Vendor.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 5000 + 1000 * (this.get_year() - 1);
        }
    }
    
    MyNamespace.Vendor.registerClass("MyNamespace.Vendor", MyNamespace.Employee);
    
    
    MyNamespace.FulltimeEmployee = function(name) {
        MyNamespace.FulltimeEmployee.initializeBase(this, [name]);
    }
    
    MyNamespace.FulltimeEmployee.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 15000 + 2000 * (this.get_year());
        }
    }
    
    MyNamespace.FulltimeEmployee.registerClass("MyNamespace.FulltimeEmployee", MyNamespace.Employee);

    这时,我们再打开刚才的页面,就会出现一个方法未实现错误,因为我们实例化一个抽象类,这不符合逻辑

    修改页面代码

    <script language="javascript" type="text/javascript">
                   function display(text) {
                       document.getElementById("info").innerHTML+=text+"<br/>";
                   }
    
                   var xiaoyaojian = new MyNamespace.Intern("Xiaoyaojian");
                   xiaoyaojian.set_year(3);
                   display(xiaoyaojian.getDescription());
    
                   var xiaobai = new MyNamespace.Vendor("Xiaobai");
                   xiaobai.set_year(3);
                   display(xiaobai.getDescription());
    
                   var xiaobaigege = new MyNamespace.FulltimeEmployee("Xiaobaigege");
                   xiaobaigege.set_year(5);
                   display(xiaobaigege.getDescription());
            </script>

    这样,成功的使用了我们创建了继承Employee的三个类

    接口

    • 与类的定义方法大致相同
    • 构造函数抛出异常
    • 所有的方法抛出异常(只有方法签名,不提供实现)
    • 注册接口时使用registerInterface方法
    • 接口无法继承其他接口

    接口定义

    • MyNamespace.IMyInterface=function(){throw Error.notImplemented()}
    • MyNamespace.IMyInterface.prototype={myMethod:function(){throw Error.notImplemented()}}
    • MyNamespace.IMyInterface.registerInterface(“MyNamespace.IMyInterface”);

    接口实现

    • 在使用registerClass方法注册类时候可以传入额外的参数来实现接口
    • MyNamespace.MyClass.registerClass("MyNamespace.IMyInterface",null,IMyInterface1,IMyInterface1,…);
    一个关于接口的示例

    同样,还是修改Employee.js文件

    /// <reference name="MicrosoftAjax.js" />
    
    Type.registerNamespace("MyNamespace"); //注册一个命名空间
    
    MyNamespace.IEmployee = function() {
        throw Error.notImplemented();
    }
    MyNamespace.IEmployee.prototype = {
        calcaulateSalary: function() {
            throw Error.notImplemented();
        }
    }
    MyNamespace.IEmployee.registerInterface("MyNamespace.IEmployee");
    
    
    MyNamespace.Employee = function(name) {//定义一个构造函数
        this._name = name ? name : "Anonymous";//初始化域变量
        this._year = 0; //初始化域变量
    }
    
    MyNamespace.Employee.prototype =//定义类成员
    {
        get_name: function() {//定义属性
            return this._name;
        },//注意都是用逗号分割的
        get_year: function() {//定义属性
            return this._year;
        },
        set_year: function(value) {//定义属性
            this._year = value;
        },
    
        calculateSalary: function() {//定义一个方法
            //return this._year * 1000;
            throw Error.notImplemented();//抛出异常,这个方法是抽象方法,说明这个类是抽象类
        },
    
        getDescription: function() {//定义一个方法
            return String.format("{0} gets {1} yuan per month", this._name, this.calculateSalary());
        }
    }
    //MyNamespace.Employee.registerClass("MyNamespace.Employee"); //注册类
    MyNamespace.Employee.registerClass("MyNamespace.Employee", null, MyNamespace.IEmployee);//注册类
    
    
    MyNamespace.Intern = function(name) {
        MyNamespace.Intern.initializeBase(this, [name]);//调用父类构造函数
    }
    
    MyNamespace.Intern.prototype =
    {
        calculateSalary: function() {
            return 2000;
    
        },
        getDescription: function() {
            var description = MyNamespace.Intern.callBaseMethod(this, "getDescription");
            return description + ",What a poor intern!";
    
        }
    }
    
    MyNamespace.Intern.registerClass("MyNamespace.Intern", MyNamespace.Employee); //注册这个类,继承MyNamespace.Employee
    
    
    MyNamespace.Vendor = function(name) {
        MyNamespace.Vendor.initializeBase(this, [name]);
    }
    
    MyNamespace.Vendor.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 5000 + 1000 * (this.get_year() - 1);
        }
    }
    
    MyNamespace.Vendor.registerClass("MyNamespace.Vendor", MyNamespace.Employee);
    
    
    MyNamespace.FulltimeEmployee = function(name) {
        MyNamespace.FulltimeEmployee.initializeBase(this, [name]);
    }
    
    MyNamespace.FulltimeEmployee.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 15000 + 2000 * (this.get_year());
        }
    }
    
    MyNamespace.FulltimeEmployee.registerClass("MyNamespace.FulltimeEmployee", MyNamespace.Employee);
    
     
     

    这时,在页面中还使用这些类还是没有问题的,如果我们要体现这个接口的继承,可以在页面<script>中添加如下代码

    display("Xiaoyaojian implements 'IEmployee' interface:" + MyNamespace.IEmployee.isImplementedBy(xiaoyaojian))

    za在页面中,我们可以看到返回的结果是true,说明Employee实现了接口IEmployee

     

    枚举

    • 枚举即为Number
    • 增加可读性
    • 可以定义为标记
    • 每个枚举类型均有toString和parse方法

    枚举的定义

    MyNamespace.MyEnum=function(){throw Error.notImplemented();}
    MyNamespace.MyEnum.prototoype={item1:1,item2:2,item3:4}
    MyNamespace.MyEnum.registerEnum(“MyNamespace.MyEnum”,[true])//true表示是否定义一个标记
    一个定义以及使用枚举的示例

    修改Employee.js

    /// <reference name="MicrosoftAjax.js" />
    
    Type.registerNamespace("MyNamespace"); //注册一个命名空间
    
    MyNamespace.EmployeeType = function() {
        throw Error.notImplemented();//抛出异常,无法实例化
    }
    MyNamespace.EmployeeType.prototype =//定义成员
    {
        Intern: 0,
        Vendor: 1,
        FulltiomEmployee: 2
    }
    MyNamespace.EmployeeType.registerEnum("MyNamespace.EmployeeType");//注册枚举
    
    MyNamespace.IEmployee = function() {
        throw Error.notImplemented();
    }
    MyNamespace.IEmployee.prototype = {
        calcaulateSalary: function() {
            throw Error.notImplemented();
        },
        get_type: function() {
            throw Error.notImplemented();
        }
    }
    MyNamespace.IEmployee.registerInterface("MyNamespace.IEmployee");
    
    
    MyNamespace.Employee = function(name) {//定义一个构造函数
        this._name = name ? name : "Anonymous";//初始化域变量
        this._year = 0; //初始化域变量
    }
    
    MyNamespace.Employee.prototype =//定义类成员
    {
        get_name: function() {//定义属性
            return this._name;
        },//注意都是用逗号分割的
        get_year: function() {//定义属性
            return this._year;
        },
        set_year: function(value) {//定义属性
            this._year = value;
        },
    
        calculateSalary: function() {//定义一个方法
            //return this._year * 1000;
            throw Error.notImplemented();//抛出异常,这个方法是抽象方法,说明这个类是抽象类
        },
    
        getDescription: function() {//定义一个方法
            return String.format("{0} gets {1} yuan per month", this._name, this.calculateSalary());
        }
    }
    //MyNamespace.Employee.registerClass("MyNamespace.Employee"); //注册类
    MyNamespace.Employee.registerClass("MyNamespace.Employee", null, MyNamespace.IEmployee);//注册类
    
    
    MyNamespace.Intern = function(name) {
        MyNamespace.Intern.initializeBase(this, [name]);//调用父类构造函数
    }
    
    MyNamespace.Intern.prototype =
    {
        calculateSalary: function() {
            return 2000;
    
        },
        getDescription: function() {
            var description = MyNamespace.Intern.callBaseMethod(this, "getDescription");
            return description + ",What a poor intern!";
    
        },
        get_type: function() {
            return MyNamespace.EmployeeType.Intern;
        }
    }
    
    MyNamespace.Intern.registerClass("MyNamespace.Intern", MyNamespace.Employee); //注册这个类,继承MyNamespace.Employee
    
    
    MyNamespace.Vendor = function(name) {
        MyNamespace.Vendor.initializeBase(this, [name]);
    }
    
    MyNamespace.Vendor.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 5000 + 1000 * (this.get_year() - 1);
        },
        get_type: function() {
            return MyNamespace.EmployeeType.Vendor;
        }
    }
    
    MyNamespace.Vendor.registerClass("MyNamespace.Vendor", MyNamespace.Employee);
    
    
    MyNamespace.FulltimeEmployee = function(name) {
        MyNamespace.FulltimeEmployee.initializeBase(this, [name]);
    }
    
    MyNamespace.FulltimeEmployee.prototype =
    {
        calculateSalary: function() {
            //return 2000;
            return 15000 + 2000 * (this.get_year());
        },
        get_type: function() {
            return MyNamespace.EmployeeType.FulltimeEmployee;
        }
    }
    
    MyNamespace.FulltimeEmployee.registerClass("MyNamespace.FulltimeEmployee", MyNamespace.Employee);
    

    这时,在页面中<script>中添加如下代码

    var type = MyNamespace.EmployeeType.toString(xiaoyaojian.get_type());
                   display(String.format("{0} is a {1}", xiaoyaojian.get_name(), type));

    刷新页面,出现效果,如果我们不使用MyNamespace.EmployeeType.toString(),这里就会出现一个“1”,符合我们的定义

    定义个作为标记的枚举类

    在Employee.js里添加如下内容

    MyNamespace.MyFlags = function() {
        throw Error.notImplemented();
    }
    MyNamespace.MyFlags.prototype =
    {
        Item1:1,
        Item2:2,
        Item3:4,
        None:0,
        All:7
    }
    MyNamespace.MyFlags.registerEnum("MyNamespace.MyFlags",true);

    在页面中我们可以这样使用

    var all = MyNamespace.MyFlags.All;
                   display(all);
                   display(MyNamespace.MyFlags.toString(all));
    
                   display(MyNamespace.MyFlags.parse("Item1,Item3")); //"Item1,Item3"这是一个标准的表示方法,结果为Item1+Item3的结果

    反射方法

    • Type.prototype.getBaseType//得到父类
    • Type.prototype.getInterfaces//得到实现的接口
    • Type.prototype.getName//得到类名
    • Type.prototype.implementsInterface//得到是否实现某接口
    • Type.prototype.inheritsFrom//确定一个类型是否从特定的基类型继承
    • Type.prototype.isImplementedBy//确定实例是否实现了特定接口
    • Type.getRootNamespaces//返回一个数组,包含对客户端应用程序的所有根命名空间的引用
    • Type.prototype.isInstanceOfType//如果当前 Type 在 object 表示的对象的继承层次结构中,或者如果当前 Type 是 object 支持的接口,则为 true
    • Type.isClass
    • Type.isInterface
    • Type.isNamespace
    • Type.isEnum
    • Type.isFlags
    • Type.parse

    后面这几个,我就不多做解释啦

    到此讲完

    今天是小白的生日,纪念一下

  • 相关阅读:
    冲刺一阶段———个人总结06
    典型用户分析
    冲刺一阶段———个人总结05
    冲刺一阶段———个人总结04
    冲刺一阶段———个人总结03
    冲刺一阶段———个人总结02
    冲刺一阶段———个人总结01
    软件需求分析
    课堂作业——寻找发帖水王
    四则运算网页版
  • 原文地址:https://www.cnblogs.com/xiaoyaojian/p/2216942.html
Copyright © 2011-2022 走看看