剖析ASP.NET AJAX的物件導向思想
1.類、成員和名字空間
在Microsoft AJAX Library中,所有的JavaScript類都繼承自object(類似於.NET Framework庫,都繼承自object),在ASP.NET AJAX應用中你可以運用物件導向的程式設計模式建立繼承自Microsoft AJAX基類的物件和元件,類有四種成員:欄位、屬性、方法、事件。欄位和屬性是名/值對,用於描述一個類的一個例項的特性的。欄位是由簡單型別構成且可直接訪問,例如:
myClassInstance.name="Fred"。
屬性可以是任何簡單型別或引用型別,通過get和set方法訪問。在ASP.NET AJAX中,get和set是獨立的函式,並規定在函式名中使用字首"get_" 或 "set_" ,例如要獲取或設定cancel屬性的值時,你可以呼叫get_cancel或set_cancel方法。
一個方法是完成一個活動的函式而不是返回一個屬性的值。屬性和方法在下面的例子裡都有示範。
事件指示特指的動作發生。當一個事件發生時,它可以呼叫一個或多個函式。事件所有者可以完成等待事件發生的任何任務。
名字空間是對關聯類的邏輯分組。名字空間使你可以對公共功能進行分組。
為了使ASP.NET Web頁面具有ASP.NET AJAX功能,你必須新增控制元件到頁面上,當頁面啟動時,參照ASP.NET AJAX庫的指令碼自動產生。
下面的例子顯示了頁面使用了控制元件。
< asp:ScriptManager runat="server" ID="scriptManager" />
下面的例子演示瞭如何使用Type.registerNamespace和.registerClass方法來把Person類增加到Demo名字空間中、建立類然後註冊類。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
在指令碼檔案Namespace.js中定義了類Person,制定了類的名字空間為"Demo"。執行頁面Namespace.aspx,點選按鈕將建立一個Demo.Person類的例項。
2.訪問修飾
許多物件導向程式語言都有訪問修飾的概念。允許你指定類或成員在某種範圍內有效。例如可在外部執行的程式、具有相同名字空間的內部類或特指的程式碼快內的類等。在JavaScript中沒有訪問修飾,但在ASP.NET AJAX中約定以下劃線字元開頭"_"的被認為是私有的,類的外部不能訪問。
3.繼承
繼承是一個類派生於另一個類的能力。派生類自動繼承基類的所有欄位、屬性、方法和事件。派生類可以增加新的成員或者重寫基類已存在的成員來改變成員的行為。
下面的指令碼例項有兩個類Person和Employee,Employee從Person繼承而來,兩個類示範了私有欄位的使用,它們都有公共屬性、方法。另外Employee類重寫了Person類的toString實現,並呼叫了基類的功能。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getEmailAddress: function() {
return this._emailAddress;
},
setEmailAddress: function(emailAddress) {
this._emailAddress = emailAddress;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
},
sendMail: function() {
var emailAddress = this.getEmailAddress();
if (emailAddress.indexOf('@') < 0) {
emailAddress = emailAddress + '@example.com';
}
alert('Sending mail to ' + emailAddress + ' ...');
},
toString: function() {
return this.getName() + ' (' + this.getEmailAddress() + ')';
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
Demo.Employee = function(firstName, lastName, emailAddress, team, title) {
Demo.Employee.initializeBase(this, [firstName, lastName, emailAddress]);
this._team = team;
this._title = title;
}
Demo.Employee.prototype = {
getTeam: function() {
return this._team;
},
setTeam: function(team) {
this._team = team;
},
getTitle: function() {
return this._title;
},
setTitle: function(title) {
this._title = title;
},
toString: function() {
return Demo.Employee.callBaseMethod(this, 'toString') + '\r\n' + this.getTitle() + '\r\n' + this.getTeam();
}
}
Demo.Employee.registerClass('Demo.Employee', Demo.Person);
Inheritance.js指令碼檔案中定義了兩個類:Person和Employee,Employee是從Person繼承而來。每個類都有欄位、公共屬性和方法。另外,Employee類重寫了toString的實現,並在重寫的程式碼中呼叫了基類的功能。在這個例子中把類Person的名字空間設定為"Demo"。執行頁面Inheritance.aspx,點選“建立物件”、“物件釋放”、“公共和私有屬性”、“物件方法”、“重寫方法”,“物件型別檢查”體驗一下。
4.介面
介面是類要實現的邏輯協議,是對類進行整合的公共遵守的規範。它能使多個類和同一個介面把實現定義和類的具體實現結合起來。下面的例子定義了一個基類Tree和介面IFruitTree,Apple和Banana這兩個類實現了介面IFruitTree,但Pine類沒有實現介面IFruitTree。
Type.registerNamespace("Demo.Trees");
Demo.Trees.IFruitTree = function() {}
Demo.Trees.IFruitTree.Prototype = {
bearFruit: function(){}
}
Demo.Trees.IFruitTree.registerInterface('Demo.Trees.IFruitTree');
Demo.Trees.Tree = function(name) {
this._name = name;
}
Demo.Trees.Tree.prototype = {
returnName: function() {
return this._name;
},
toStringCustom: function() {
return this.returnName();
},
makeLeaves: function() {}
}
Demo.Trees.Tree.registerClass('Demo.Trees.Tree');
Demo.Trees.FruitTree = function(name, description) {
Demo.Trees.FruitTree.initializeBase(this, [name]);
this._description = description;
}
Demo.Trees.FruitTree.prototype.bearFruit = function() {
return this._description;
}
Demo.Trees.FruitTree.registerClass('Demo.Trees.FruitTree', Demo.Trees.Tree, Demo.Trees.IFruitTree);
Demo.Trees.Apple = function() {
Demo.Trees.Apple.initializeBase(this, ['Apple', 'red and crunchy']);
}
Demo.Trees.Apple.prototype = {
makeLeaves: function() {
alert('Medium-sized and desiduous');
},
toStringCustom: function() {
return 'FruitTree ' + Demo.Trees.Apple.callBaseMethod(this, 'toStringCustom');
}
}
Demo.Trees.Apple.registerClass('Demo.Trees.Apple', Demo.Trees.FruitTree);
Demo.Trees.GrannySmith = function() {
Demo.Trees.GrannySmith.initializeBase(this);
// You must set the _description feild after initializeBase
// or you will get the base value.
this._description = 'green and sour';
}
Demo.Trees.GrannySmith.prototype.toStringCustom = function() {
return Demo.Trees.GrannySmith.callBaseMethod(this, 'toStringCustom') + ' ... its GrannySmith!';
}
Demo.Trees.GrannySmith.registerClass('Demo.Trees.GrannySmith', Demo.Trees.Apple);
Demo.Trees.Banana = function(description) {
Demo.Trees.Banana.initializeBase(this, ['Banana', 'yellow and squishy']);
}
Demo.Trees.Banana.prototype.makeLeaves = function() {
alert('Big and green');
}
Demo.Trees.Banana.registerClass('Demo.Trees.Banana', Demo.Trees.FruitTree);
Demo.Trees.Pine = function() {
Demo.Trees.Pine.initializeBase(this, ['Pine']);
}
Demo.Trees.Pine.prototype.makeLeaves = function() {
alert('Needles in clusters');
}
Demo.Trees.Pine.registerClass('Demo.Trees.Pine', Demo.Trees.Tree);
Interface.js指令碼檔案中定義了一個Tree基類和一個IFruitTree介面。Apple和Banana兩個繼承類實現了IFruitTree介面,而Pine類沒有實現IFruitTree介面。執行Interface.aspx,點選“物件建立”、“介面檢查”、“呼叫介面方法”體驗一下。
5.列舉
列舉是包含一組被命名的正整數常數的類。你可以像訪問屬性一樣訪問它的值。例如:
myObject.color = myColorEnum.red,列舉提供了一種很容易理解的整數表示。下面的例子定義了一個以十六進位制數表示的顏色被命名為有意義的名字的列舉型別。
Type.registerNamespace("Demo");
// Define an enumeration type and register it.
Demo.Color = function(){};
Demo.Color.prototype =
{
Red: 0xFF0000,
Blue: 0x0000FF,
Green: 0x00FF00,
White: 0xFFFFFF
}
Demo.Color.registerEnum("Demo.Color");
執行Enumeration.aspx,選擇下拉框中的顏色,指令碼程式把背景色設為選中的列舉型別Demo.Color中的顏色。
6.反射
反射用於檢查一個執行期程式的結構和組成,是通過類Type的API來實現反射的,這些方法使你能夠收集一個物件的資訊,例如:它是繼承於哪個類、它是否實現類某個特指的介面、它是否是某個類的例項等。
下面的例子用反射的API測試GrannySmith類是否實現了前面的介面。執行Reflection.aspx,點選“檢查型別”、“檢查繼承”、“檢查介面”體驗一下。
另外需要說明的一點是,Microsoft AJAX Library是基於開放體系架構而開發的,不僅僅用於asp.net,還能用於其它體系架構中,例如用在java中。
人們期待已久的ASP.NET AJAX v1.0正式版終於釋出了。現在你能用Microsoft ASP.NET AJAX的javascript很容易的寫出豐富的、互動式的web應用。尤其值得關注的是Microsoft AJAX Library增加了物件導向的支援,而以前javascript是不支援物件導向開發的。現在icrosoft AJAX Library能很好的支援類、名字空間、繼承、介面、列舉、反射等特徵。這些新增加的功能類似於.NET Framework,這使得開發ASP.NET AJAX應用變得容易維護,容易擴充。現在我們看看Microsoft AJAX Library是如何支援以上特徵的。
1.類、成員和名字空間
在Microsoft AJAX Library中,所有的JavaScript類都繼承自object(類似於.NET Framework庫,都繼承自object),在ASP.NET AJAX應用中你可以運用物件導向的程式設計模式建立繼承自Microsoft AJAX基類的物件和元件,類有四種成員:欄位、屬性、方法、事件。欄位和屬性是名/值對,用於描述一個類的一個例項的特性的。欄位是由簡單型別構成且可直接訪問,例如:
myClassInstance.name="Fred"。
屬性可以是任何簡單型別或引用型別,通過get和set方法訪問。在ASP.NET AJAX中,get和set是獨立的函式,並規定在函式名中使用字首"get_" 或 "set_" ,例如要獲取或設定cancel屬性的值時,你可以呼叫get_cancel或set_cancel方法。
一個方法是完成一個活動的函式而不是返回一個屬性的值。屬性和方法在下面的例子裡都有示範。
事件指示特指的動作發生。當一個事件發生時,它可以呼叫一個或多個函式。事件所有者可以完成等待事件發生的任何任務。
名字空間是對關聯類的邏輯分組。名字空間使你可以對公共功能進行分組。
為了使ASP.NET Web頁面具有ASP.NET AJAX功能,你必須新增控制元件到頁面上,當頁面啟動時,參照ASP.NET AJAX庫的指令碼自動產生。
下面的例子顯示了頁面使用了控制元件。
< asp:ScriptManager runat="server" ID="scriptManager" />
下面的例子演示瞭如何使用Type.registerNamespace和.registerClass方法來把Person類增加到Demo名字空間中、建立類然後註冊類。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
在指令碼檔案Namespace.js中定義了類Person,制定了類的名字空間為"Demo"。執行頁面Namespace.aspx,點選按鈕將建立一個Demo.Person類的例項。
2.訪問修飾
許多物件導向程式語言都有訪問修飾的概念。允許你指定類或成員在某種範圍內有效。例如可在外部執行的程式、具有相同名字空間的內部類或特指的程式碼快內的類等。在JavaScript中沒有訪問修飾,但在ASP.NET AJAX中約定以下劃線字元開頭"_"的被認為是私有的,類的外部不能訪問。
3.繼承
繼承是一個類派生於另一個類的能力。派生類自動繼承基類的所有欄位、屬性、方法和事件。派生類可以增加新的成員或者重寫基類已存在的成員來改變成員的行為。
下面的指令碼例項有兩個類Person和Employee,Employee從Person繼承而來,兩個類示範了私有欄位的使用,它們都有公共屬性、方法。另外Employee類重寫了Person類的toString實現,並呼叫了基類的功能。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getEmailAddress: function() {
return this._emailAddress;
},
setEmailAddress: function(emailAddress) {
this._emailAddress = emailAddress;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
},
sendMail: function() {
var emailAddress = this.getEmailAddress();
if (emailAddress.indexOf('@') < 0) {
emailAddress = emailAddress + '@example.com';
}
alert('Sending mail to ' + emailAddress + ' ...');
},
toString: function() {
return this.getName() + ' (' + this.getEmailAddress() + ')';
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
Demo.Employee = function(firstName, lastName, emailAddress, team, title) {
Demo.Employee.initializeBase(this, [firstName, lastName, emailAddress]);
this._team = team;
this._title = title;
}
Demo.Employee.prototype = {
getTeam: function() {
return this._team;
},
setTeam: function(team) {
this._team = team;
},
getTitle: function() {
return this._title;
},
setTitle: function(title) {
this._title = title;
},
toString: function() {
return Demo.Employee.callBaseMethod(this, 'toString') + '\r\n' + this.getTitle() + '\r\n' + this.getTeam();
}
}
Demo.Employee.registerClass('Demo.Employee', Demo.Person);
Inheritance.js指令碼檔案中定義了兩個類:Person和Employee,Employee是從Person繼承而來。每個類都有欄位、公共屬性和方法。另外,Employee類重寫了toString的實現,並在重寫的程式碼中呼叫了基類的功能。在這個例子中把類Person的名字空間設定為"Demo"。執行頁面Inheritance.aspx,點選“建立物件”、“物件釋放”、“公共和私有屬性”、“物件方法”、“重寫方法”,“物件型別檢查”體驗一下。
4.介面
介面是類要實現的邏輯協議,是對類進行整合的公共遵守的規範。它能使多個類和同一個介面把實現定義和類的具體實現結合起來。下面的例子定義了一個基類Tree和介面IFruitTree,Apple和Banana這兩個類實現了介面IFruitTree,但Pine類沒有實現介面IFruitTree。
Type.registerNamespace("Demo.Trees");
Demo.Trees.IFruitTree = function() {}
Demo.Trees.IFruitTree.Prototype = {
bearFruit: function(){}
}
Demo.Trees.IFruitTree.registerInterface('Demo.Trees.IFruitTree');
Demo.Trees.Tree = function(name) {
this._name = name;
}
Demo.Trees.Tree.prototype = {
returnName: function() {
return this._name;
},
toStringCustom: function() {
return this.returnName();
},
makeLeaves: function() {}
}
Demo.Trees.Tree.registerClass('Demo.Trees.Tree');
Demo.Trees.FruitTree = function(name, description) {
Demo.Trees.FruitTree.initializeBase(this, [name]);
this._description = description;
}
Demo.Trees.FruitTree.prototype.bearFruit = function() {
return this._description;
}
Demo.Trees.FruitTree.registerClass('Demo.Trees.FruitTree', Demo.Trees.Tree, Demo.Trees.IFruitTree);
Demo.Trees.Apple = function() {
Demo.Trees.Apple.initializeBase(this, ['Apple', 'red and crunchy']);
}
Demo.Trees.Apple.prototype = {
makeLeaves: function() {
alert('Medium-sized and desiduous');
},
toStringCustom: function() {
return 'FruitTree ' + Demo.Trees.Apple.callBaseMethod(this, 'toStringCustom');
}
}
Demo.Trees.Apple.registerClass('Demo.Trees.Apple', Demo.Trees.FruitTree);
Demo.Trees.GrannySmith = function() {
Demo.Trees.GrannySmith.initializeBase(this);
// You must set the _description feild after initializeBase
// or you will get the base value.
this._description = 'green and sour';
}
Demo.Trees.GrannySmith.prototype.toStringCustom = function() {
return Demo.Trees.GrannySmith.callBaseMethod(this, 'toStringCustom') + ' ... its GrannySmith!';
}
Demo.Trees.GrannySmith.registerClass('Demo.Trees.GrannySmith', Demo.Trees.Apple);
Demo.Trees.Banana = function(description) {
Demo.Trees.Banana.initializeBase(this, ['Banana', 'yellow and squishy']);
}
Demo.Trees.Banana.prototype.makeLeaves = function() {
alert('Big and green');
}
Demo.Trees.Banana.registerClass('Demo.Trees.Banana', Demo.Trees.FruitTree);
Demo.Trees.Pine = function() {
Demo.Trees.Pine.initializeBase(this, ['Pine']);
}
Demo.Trees.Pine.prototype.makeLeaves = function() {
alert('Needles in clusters');
}
Demo.Trees.Pine.registerClass('Demo.Trees.Pine', Demo.Trees.Tree);
Interface.js指令碼檔案中定義了一個Tree基類和一個IFruitTree介面。Apple和Banana兩個繼承類實現了IFruitTree介面,而Pine類沒有實現IFruitTree介面。執行Interface.aspx,點選“物件建立”、“介面檢查”、“呼叫介面方法”體驗一下。
5.列舉
列舉是包含一組被命名的正整數常數的類。你可以像訪問屬性一樣訪問它的值。例如:
myObject.color = myColorEnum.red,列舉提供了一種很容易理解的整數表示。下面的例子定義了一個以十六進位制數表示的顏色被命名為有意義的名字的列舉型別。
Type.registerNamespace("Demo");
// Define an enumeration type and register it.
Demo.Color = function(){};
Demo.Color.prototype =
{
Red: 0xFF0000,
Blue: 0x0000FF,
Green: 0x00FF00,
White: 0xFFFFFF
}
Demo.Color.registerEnum("Demo.Color");
執行Enumeration.aspx,選擇下拉框中的顏色,指令碼程式把背景色設為選中的列舉型別Demo.Color中的顏色。
6.反射
反射用於檢查一個執行期程式的結構和組成,是通過類Type的API來實現反射的,這些方法使你能夠收集一個物件的資訊,例如:它是繼承於哪個類、它是否實現類某個特指的介面、它是否是某個類的例項等。
下面的例子用反射的API測試GrannySmith類是否實現了前面的介面。執行Reflection.aspx,點選“檢查型別”、“檢查繼承”、“檢查介面”體驗一下。
另外需要說明的一點是,Microsoft AJAX Library是基於開放體系架構而開發的,不僅僅用於asp.net,還能用於其它體系架構中,例如用在java中。
人們期待已久的ASP.NET AJAX v1.0正式版終於釋出了。現在你能用Microsoft ASP.NET AJAX的javascript很容易的寫出豐富的、互動式的web應用。尤其值得關注的是Microsoft AJAX Library增加了物件導向的支援,而以前javascript是不支援物件導向開發的。現在icrosoft AJAX Library能很好的支援類、名字空間、繼承、介面、列舉、反射等特徵。這些新增加的功能類似於.NET Framework,這使得開發ASP.NET AJAX應用變得容易維護,容易擴充。現在我們看看Microsoft AJAX Library是如何支援以上特徵的。
1.類、成員和名字空間
在Microsoft AJAX Library中,所有的JavaScript類都繼承自object(類似於.NET Framework庫,都繼承自object),在ASP.NET AJAX應用中你可以運用物件導向的程式設計模式建立繼承自Microsoft AJAX基類的物件和元件,類有四種成員:欄位、屬性、方法、事件。欄位和屬性是名/值對,用於描述一個類的一個例項的特性的。欄位是由簡單型別構成且可直接訪問,例如:
myClassInstance.name="Fred"。
屬性可以是任何簡單型別或引用型別,通過get和set方法訪問。在ASP.NET AJAX中,get和set是獨立的函式,並規定在函式名中使用字首"get_" 或 "set_" ,例如要獲取或設定cancel屬性的值時,你可以呼叫get_cancel或set_cancel方法。
一個方法是完成一個活動的函式而不是返回一個屬性的值。屬性和方法在下面的例子裡都有示範。
事件指示特指的動作發生。當一個事件發生時,它可以呼叫一個或多個函式。事件所有者可以完成等待事件發生的任何任務。
名字空間是對關聯類的邏輯分組。名字空間使你可以對公共功能進行分組。
為了使ASP.NET Web頁面具有ASP.NET AJAX功能,你必須新增控制元件到頁面上,當頁面啟動時,參照ASP.NET AJAX庫的指令碼自動產生。
下面的例子顯示了頁面使用了控制元件。
< asp:ScriptManager runat="server" ID="scriptManager" />
下面的例子演示瞭如何使用Type.registerNamespace和.registerClass方法來把Person類增加到Demo名字空間中、建立類然後註冊類。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
在指令碼檔案Namespace.js中定義了類Person,制定了類的名字空間為"Demo"。執行頁面Namespace.aspx,點選按鈕將建立一個Demo.Person類的例項。
2.訪問修飾
許多物件導向程式語言都有訪問修飾的概念。允許你指定類或成員在某種範圍內有效。例如可在外部執行的程式、具有相同名字空間的內部類或特指的程式碼快內的類等。在JavaScript中沒有訪問修飾,但在ASP.NET AJAX中約定以下劃線字元開頭"_"的被認為是私有的,類的外部不能訪問。
3.繼承
繼承是一個類派生於另一個類的能力。派生類自動繼承基類的所有欄位、屬性、方法和事件。派生類可以增加新的成員或者重寫基類已存在的成員來改變成員的行為。
下面的指令碼例項有兩個類Person和Employee,Employee從Person繼承而來,兩個類示範了私有欄位的使用,它們都有公共屬性、方法。另外Employee類重寫了Person類的toString實現,並呼叫了基類的功能。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getEmailAddress: function() {
return this._emailAddress;
},
setEmailAddress: function(emailAddress) {
this._emailAddress = emailAddress;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
},
sendMail: function() {
var emailAddress = this.getEmailAddress();
if (emailAddress.indexOf('@') < 0) {
emailAddress = emailAddress + '@example.com';
}
alert('Sending mail to ' + emailAddress + ' ...');
},
toString: function() {
return this.getName() + ' (' + this.getEmailAddress() + ')';
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
Demo.Employee = function(firstName, lastName, emailAddress, team, title) {
Demo.Employee.initializeBase(this, [firstName, lastName, emailAddress]);
this._team = team;
this._title = title;
}
Demo.Employee.prototype = {
getTeam: function() {
return this._team;
},
setTeam: function(team) {
this._team = team;
},
getTitle: function() {
return this._title;
},
setTitle: function(title) {
this._title = title;
},
toString: function() {
return Demo.Employee.callBaseMethod(this, 'toString') + '\r\n' + this.getTitle() + '\r\n' + this.getTeam();
}
}
Demo.Employee.registerClass('Demo.Employee', Demo.Person);
Inheritance.js指令碼檔案中定義了兩個類:Person和Employee,Employee是從Person繼承而來。每個類都有欄位、公共屬性和方法。另外,Employee類重寫了toString的實現,並在重寫的程式碼中呼叫了基類的功能。在這個例子中把類Person的名字空間設定為"Demo"。執行頁面Inheritance.aspx,點選“建立物件”、“物件釋放”、“公共和私有屬性”、“物件方法”、“重寫方法”,“物件型別檢查”體驗一下。
4.介面
介面是類要實現的邏輯協議,是對類進行整合的公共遵守的規範。它能使多個類和同一個介面把實現定義和類的具體實現結合起來。下面的例子定義了一個基類Tree和介面IFruitTree,Apple和Banana這兩個類實現了介面IFruitTree,但Pine類沒有實現介面IFruitTree。
Type.registerNamespace("Demo.Trees");
Demo.Trees.IFruitTree = function() {}
Demo.Trees.IFruitTree.Prototype = {
bearFruit: function(){}
}
Demo.Trees.IFruitTree.registerInterface('Demo.Trees.IFruitTree');
Demo.Trees.Tree = function(name) {
this._name = name;
}
Demo.Trees.Tree.prototype = {
returnName: function() {
return this._name;
},
toStringCustom: function() {
return this.returnName();
},
makeLeaves: function() {}
}
Demo.Trees.Tree.registerClass('Demo.Trees.Tree');
Demo.Trees.FruitTree = function(name, description) {
Demo.Trees.FruitTree.initializeBase(this, [name]);
this._description = description;
}
Demo.Trees.FruitTree.prototype.bearFruit = function() {
return this._description;
}
Demo.Trees.FruitTree.registerClass('Demo.Trees.FruitTree', Demo.Trees.Tree, Demo.Trees.IFruitTree);
Demo.Trees.Apple = function() {
Demo.Trees.Apple.initializeBase(this, ['Apple', 'red and crunchy']);
}
Demo.Trees.Apple.prototype = {
makeLeaves: function() {
alert('Medium-sized and desiduous');
},
toStringCustom: function() {
return 'FruitTree ' + Demo.Trees.Apple.callBaseMethod(this, 'toStringCustom');
}
}
Demo.Trees.Apple.registerClass('Demo.Trees.Apple', Demo.Trees.FruitTree);
Demo.Trees.GrannySmith = function() {
Demo.Trees.GrannySmith.initializeBase(this);
// You must set the _description feild after initializeBase
// or you will get the base value.
this._description = 'green and sour';
}
Demo.Trees.GrannySmith.prototype.toStringCustom = function() {
return Demo.Trees.GrannySmith.callBaseMethod(this, 'toStringCustom') + ' ... its GrannySmith!';
}
Demo.Trees.GrannySmith.registerClass('Demo.Trees.GrannySmith', Demo.Trees.Apple);
Demo.Trees.Banana = function(description) {
Demo.Trees.Banana.initializeBase(this, ['Banana', 'yellow and squishy']);
}
Demo.Trees.Banana.prototype.makeLeaves = function() {
alert('Big and green');
}
Demo.Trees.Banana.registerClass('Demo.Trees.Banana', Demo.Trees.FruitTree);
Demo.Trees.Pine = function() {
Demo.Trees.Pine.initializeBase(this, ['Pine']);
}
Demo.Trees.Pine.prototype.makeLeaves = function() {
alert('Needles in clusters');
}
Demo.Trees.Pine.registerClass('Demo.Trees.Pine', Demo.Trees.Tree);
Interface.js指令碼檔案中定義了一個Tree基類和一個IFruitTree介面。Apple和Banana兩個繼承類實現了IFruitTree介面,而Pine類沒有實現IFruitTree介面。執行Interface.aspx,點選“物件建立”、“介面檢查”、“呼叫介面方法”體驗一下。
5.列舉
列舉是包含一組被命名的正整數常數的類。你可以像訪問屬性一樣訪問它的值。例如:
myObject.color = myColorEnum.red,列舉提供了一種很容易理解的整數表示。下面的例子定義了一個以十六進位制數表示的顏色被命名為有意義的名字的列舉型別。
Type.registerNamespace("Demo");
// Define an enumeration type and register it.
Demo.Color = function(){};
Demo.Color.prototype =
{
Red: 0xFF0000,
Blue: 0x0000FF,
Green: 0x00FF00,
White: 0xFFFFFF
}
Demo.Color.registerEnum("Demo.Color");
執行Enumeration.aspx,選擇下拉框中的顏色,指令碼程式把背景色設為選中的列舉型別Demo.Color中的顏色。
6.反射
反射用於檢查一個執行期程式的結構和組成,是通過類Type的API來實現反射的,這些方法使你能夠收集一個物件的資訊,例如:它是繼承於哪個類、它是否實現類某個特指的介面、它是否是某個類的例項等。
下面的例子用反射的API測試GrannySmith類是否實現了前面的介面。執行Reflection.aspx,點選“檢查型別”、“檢查繼承”、“檢查介面”體驗一下。
另外需要說明的一點是,Microsoft AJAX Library是基於開放體系架構而開發的,不僅僅用於asp.net,還能用於其它體系架構中,例如用在java中。
人們期待已久的ASP.NET AJAX v1.0正式版終於釋出了。現在你能用Microsoft ASP.NET AJAX的javascript很容易的寫出豐富的、互動式的web應用。尤其值得關注的是Microsoft AJAX Library增加了物件導向的支援,而以前javascript是不支援物件導向開發的。現在icrosoft AJAX Library能很好的支援類、名字空間、繼承、介面、列舉、反射等特徵。這些新增加的功能類似於.NET Framework,這使得開發ASP.NET AJAX應用變得容易維護,容易擴充。現在我們看看Microsoft AJAX Library是如何支援以上特徵的。
1.類、成員和名字空間
在Microsoft AJAX Library中,所有的JavaScript類都繼承自object(類似於.NET Framework庫,都繼承自object),在ASP.NET AJAX應用中你可以運用物件導向的程式設計模式建立繼承自Microsoft AJAX基類的物件和元件,類有四種成員:欄位、屬性、方法、事件。欄位和屬性是名/值對,用於描述一個類的一個例項的特性的。欄位是由簡單型別構成且可直接訪問,例如:
myClassInstance.name="Fred"。
屬性可以是任何簡單型別或引用型別,通過get和set方法訪問。在ASP.NET AJAX中,get和set是獨立的函式,並規定在函式名中使用字首"get_" 或 "set_" ,例如要獲取或設定cancel屬性的值時,你可以呼叫get_cancel或set_cancel方法。
一個方法是完成一個活動的函式而不是返回一個屬性的值。屬性和方法在下面的例子裡都有示範。
事件指示特指的動作發生。當一個事件發生時,它可以呼叫一個或多個函式。事件所有者可以完成等待事件發生的任何任務。
名字空間是對關聯類的邏輯分組。名字空間使你可以對公共功能進行分組。
為了使ASP.NET Web頁面具有ASP.NET AJAX功能,你必須新增控制元件到頁面上,當頁面啟動時,參照ASP.NET AJAX庫的指令碼自動產生。
下面的例子顯示了頁面使用了控制元件。
< asp:ScriptManager runat="server" ID="scriptManager" />
下面的例子演示瞭如何使用Type.registerNamespace和.registerClass方法來把Person類增加到Demo名字空間中、建立類然後註冊類。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
在指令碼檔案Namespace.js中定義了類Person,制定了類的名字空間為"Demo"。執行頁面Namespace.aspx,點選按鈕將建立一個Demo.Person類的例項。
2.訪問修飾
許多物件導向程式語言都有訪問修飾的概念。允許你指定類或成員在某種範圍內有效。例如可在外部執行的程式、具有相同名字空間的內部類或特指的程式碼快內的類等。在JavaScript中沒有訪問修飾,但在ASP.NET AJAX中約定以下劃線字元開頭"_"的被認為是私有的,類的外部不能訪問。
3.繼承
繼承是一個類派生於另一個類的能力。派生類自動繼承基類的所有欄位、屬性、方法和事件。派生類可以增加新的成員或者重寫基類已存在的成員來改變成員的行為。
下面的指令碼例項有兩個類Person和Employee,Employee從Person繼承而來,兩個類示範了私有欄位的使用,它們都有公共屬性、方法。另外Employee類重寫了Person類的toString實現,並呼叫了基類的功能。
Type.registerNamespace("Demo");
Demo.Person = function(firstName, lastName, emailAddress) {
this._firstName = firstName;
this._lastName = lastName;
this._emailAddress = emailAddress;
}
Demo.Person.prototype = {
getFirstName: function() {
return this._firstName;
},
getLastName: function() {
return this._lastName;
},
getEmailAddress: function() {
return this._emailAddress;
},
setEmailAddress: function(emailAddress) {
this._emailAddress = emailAddress;
},
getName: function() {
return this._firstName + ' ' + this._lastName;
},
dispose: function() {
alert('bye ' + this.getName());
},
sendMail: function() {
var emailAddress = this.getEmailAddress();
if (emailAddress.indexOf('@') < 0) {
emailAddress = emailAddress + '@example.com';
}
alert('Sending mail to ' + emailAddress + ' ...');
},
toString: function() {
return this.getName() + ' (' + this.getEmailAddress() + ')';
}
}
Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);
Demo.Employee = function(firstName, lastName, emailAddress, team, title) {
Demo.Employee.initializeBase(this, [firstName, lastName, emailAddress]);
this._team = team;
this._title = title;
}
Demo.Employee.prototype = {
getTeam: function() {
return this._team;
},
setTeam: function(team) {
this._team = team;
},
getTitle: function() {
return this._title;
},
setTitle: function(title) {
this._title = title;
},
toString: function() {
return Demo.Employee.callBaseMethod(this, 'toString') + '\r\n' + this.getTitle() + '\r\n' + this.getTeam();
}
}
Demo.Employee.registerClass('Demo.Employee', Demo.Person);
Inheritance.js指令碼檔案中定義了兩個類:Person和Employee,Employee是從Person繼承而來。每個類都有欄位、公共屬性和方法。另外,Employee類重寫了toString的實現,並在重寫的程式碼中呼叫了基類的功能。在這個例子中把類Person的名字空間設定為"Demo"。執行頁面Inheritance.aspx,點選“建立物件”、“物件釋放”、“公共和私有屬性”、“物件方法”、“重寫方法”,“物件型別檢查”體驗一下。
4.介面
介面是類要實現的邏輯協議,是對類進行整合的公共遵守的規範。它能使多個類和同一個介面把實現定義和類的具體實現結合起來。下面的例子定義了一個基類Tree和介面IFruitTree,Apple和Banana這兩個類實現了介面IFruitTree,但Pine類沒有實現介面IFruitTree。
Type.registerNamespace("Demo.Trees");
Demo.Trees.IFruitTree = function() {}
Demo.Trees.IFruitTree.Prototype = {
bearFruit: function(){}
}
Demo.Trees.IFruitTree.registerInterface('Demo.Trees.IFruitTree');
Demo.Trees.Tree = function(name) {
this._name = name;
}
Demo.Trees.Tree.prototype = {
returnName: function() {
return this._name;
},
toStringCustom: function() {
return this.returnName();
},
makeLeaves: function() {}
}
Demo.Trees.Tree.registerClass('Demo.Trees.Tree');
Demo.Trees.FruitTree = function(name, description) {
Demo.Trees.FruitTree.initializeBase(this, [name]);
this._description = description;
}
Demo.Trees.FruitTree.prototype.bearFruit = function() {
return this._description;
}
Demo.Trees.FruitTree.registerClass('Demo.Trees.FruitTree', Demo.Trees.Tree, Demo.Trees.IFruitTree);
Demo.Trees.Apple = function() {
Demo.Trees.Apple.initializeBase(this, ['Apple', 'red and crunchy']);
}
Demo.Trees.Apple.prototype = {
makeLeaves: function() {
alert('Medium-sized and desiduous');
},
toStringCustom: function() {
return 'FruitTree ' + Demo.Trees.Apple.callBaseMethod(this, 'toStringCustom');
}
}
Demo.Trees.Apple.registerClass('Demo.Trees.Apple', Demo.Trees.FruitTree);
Demo.Trees.GrannySmith = function() {
Demo.Trees.GrannySmith.initializeBase(this);
// You must set the _description feild after initializeBase
// or you will get the base value.
this._description = 'green and sour';
}
Demo.Trees.GrannySmith.prototype.toStringCustom = function() {
return Demo.Trees.GrannySmith.callBaseMethod(this, 'toStringCustom') + ' ... its GrannySmith!';
}
Demo.Trees.GrannySmith.registerClass('Demo.Trees.GrannySmith', Demo.Trees.Apple);
Demo.Trees.Banana = function(description) {
Demo.Trees.Banana.initializeBase(this, ['Banana', 'yellow and squishy']);
}
Demo.Trees.Banana.prototype.makeLeaves = function() {
alert('Big and green');
}
Demo.Trees.Banana.registerClass('Demo.Trees.Banana', Demo.Trees.FruitTree);
Demo.Trees.Pine = function() {
Demo.Trees.Pine.initializeBase(this, ['Pine']);
}
Demo.Trees.Pine.prototype.makeLeaves = function() {
alert('Needles in clusters');
}
Demo.Trees.Pine.registerClass('Demo.Trees.Pine', Demo.Trees.Tree);
Interface.js指令碼檔案中定義了一個Tree基類和一個IFruitTree介面。Apple和Banana兩個繼承類實現了IFruitTree介面,而Pine類沒有實現IFruitTree介面。執行Interface.aspx,點選“物件建立”、“介面檢查”、“呼叫介面方法”體驗一下。
5.列舉
列舉是包含一組被命名的正整數常數的類。你可以像訪問屬性一樣訪問它的值。例如:
myObject.color = myColorEnum.red,列舉提供了一種很容易理解的整數表示。下面的例子定義了一個以十六進位制數表示的顏色被命名為有意義的名字的列舉型別。
Type.registerNamespace("Demo");
// Define an enumeration type and register it.
Demo.Color = function(){};
Demo.Color.prototype =
{
Red: 0xFF0000,
Blue: 0x0000FF,
Green: 0x00FF00,
White: 0xFFFFFF
}
Demo.Color.registerEnum("Demo.Color");
執行Enumeration.aspx,選擇下拉框中的顏色,指令碼程式把背景色設為選中的列舉型別Demo.Color中的顏色。
6.反射
反射用於檢查一個執行期程式的結構和組成,是通過類Type的API來實現反射的,這些方法使你能夠收集一個物件的資訊,例如:它是繼承於哪個類、它是否實現類某個特指的介面、它是否是某個類的例項等。
下面的例子用反射的API測試GrannySmith類是否實現了前面的介面。執行Reflection.aspx,點選“檢查型別”、“檢查繼承”、“檢查介面”體驗一下。
另外需要說明的一點是,Microsoft AJAX Library是基於開放體系架構而開發的,不僅僅用於asp.net,還能用於其它體系架構中,例如用在java中。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-526835/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 物件導向-物件導向思想物件
- 物件導向思想物件
- JAVA物件導向思想Java物件
- 物件導向思想的核心概念物件
- 在ASP.NET中物件導向的程式設計思想 (轉)ASP.NET物件程式設計
- 問答題:物件導向的思想物件
- JavaScript 物件導向實戰思想JavaScript物件
- 程式設計思想 物件導向程式設計物件
- python物件導向思想(類與物件)Python物件
- 物件導向程式設計,我的思想[上]物件程式設計
- 物件導向程式設計,我的思想[下]物件程式設計
- 從物件導向解讀設計思想物件
- 萬字長文深度剖析物件導向的javascript物件JavaScript
- go物件導向思想:封裝、繼承、多肽Go物件封裝繼承
- 面試——談談你對Java 物件導向思想的理解面試Java物件
- 淺談物件導向中的一些主要思想物件
- 請用物件導向的思想,談一談面試的過程物件面試
- C#之淺析物件導向程式設計思想(二)C#物件程式設計
- 程式導向與物件導向物件
- 物件導向與程式導向物件
- “程序導向”和“物件導向”物件
- 從物件導向到模式再到真正的物件導向 (轉)物件模式
- C#學習筆記(一)--- 物件導向的思想和類的定義、物件的建立C#筆記物件
- 物件導向物件
- java的物件導向Java物件
- JavaScript的物件導向JavaScript物件
- 什麼是物件?什麼是抽象?怎麼理解物件導向的程式設計思想?物件抽象程式設計
- php中的程式導向與物件導向PHP物件
- 看完這篇,真正理解JS物件導向程式設計思想JS物件程式設計
- 物件導向,搞定物件物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- JAVA物件導向基礎--物件導向介紹Java物件
- Python基礎系列講解——物件導向體系的概念剖析Python物件
- 從程式導向到物件導向物件
- 一覺醒來多了無數個物件,秒走人生巔峰?(java物件導向思想)物件Java
- 物件導向(下)物件
- 物件導向 -- 反射物件反射
- PHP物件導向PHP物件