ASP.NET AJAX(6)__Microsoft AJAX Library中的面向对象类型系统命名空间类类——构造函数类——定义方法类——定义属性类——注册类类——抽象类类——继承类——调用父类方
时间:2022-05-03
本文章向大家介绍ASP.NET AJAX(6)__Microsoft AJAX Library中的面向对象类型系统命名空间类类——构造函数类——定义方法类——定义属性类——注册类类——抽象类类——继承类——调用父类方,主要内容包括命名空间、类、类——构造函数、类——定义方法、类——定义属性、类——注册类、类——抽象类、类——继承、类——调用父类方法、接口、枚举、反射方法、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
如果我们可以合理的使用面向对象编程,我们可以提高代码的复用性和可维护性,这里强调的是合理的使用,有了面向对象类型系统,就可以使用一些成熟的设计方式
命名空间
- 合理的组织大量的类型,使开发人员能够方便的找到他们所需要的类型
- 可重复注册命名空间,每个独立的脚本模块前都要注册命名空间以保证命名空间存在
类
- 定义构造函数
- 定义成员(方法、属性、事件)
- 注册类
类——构造函数
- 类的构造函数即为function定义
- 通常用于初始化域变量
- 自由成员使用下划线开头(形式上的封装)
类——定义方法
- 使用prototype定义
- MyNamespace.MyClass.prototype={method1:function{},method2:function()}
类——定义属性
- Microsoft AJAX Library的面向对象类型系统将get_xxx和set_xxx开头的方法认做属性(一种约定)
- 避免定义只写属性,使用某个方法替代
类——注册类
- Tye.registerNamespace("MyNamespace");
- MyNamespace.MyClass=function(parm1,…){…}
- MyNamespace.MyClass.prototype={…}
- 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
后面这几个,我就不多做解释啦
到此讲完
今天是小白的生日,纪念一下
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 2015.CCF计算机软件能力认证试题第二题
- Codeforces Round #547 (Div. 3)A. Game 23
- Codeforces Round #547 (Div. 3)C. Polycarp Restores Permutation
- 动态规划入门_数塔问题
- Rust所有者被修改了会发生什么?
- 如何编写高质量代码
- 动态规划入门_钱币兑换问题
- Codeforces Round #547 (Div. 3)D. Colored Boots
- JavaScript 性能优化
- 优化循环的方法-循环展开
- 程序性能优化-局部性原理
- Codeforces Round #547 (Div. 3)E. Superhero Battle
- 《动态规划_入门 LIS 问题 》
- 栅格化系统的原理以及实现
- vue-qr二维码插件使用简介