|
關(guān)鍵字: javascript設(shè)計(jì)模式
從類繼承 到這里,我們已經(jīng)了解了構(gòu)造函數(shù)和原型對(duì)象如何使您在JavaScript中模擬類。您可以看到,原型鏈可以確保所有對(duì)象都有Object.prototype的公用方法,以及如何使用閉包來(lái)模擬類的私有成員。但這里還缺少點(diǎn)什么。您尚未看到如何從類派生,這在C#中是每天必做的工作。遺憾的是,在JavaScript中從類繼承并非像在C#中鍵入冒號(hào)即可繼承那樣簡(jiǎn)單,它需要進(jìn)行更多操作。另一方面,JavaScript非常靈活,可以有很多從類繼承的方式。 例如,有一個(gè)積累Pet,它有一個(gè)派生類Dog,如圖9所示。這個(gè)在JavaScript中如何實(shí)現(xiàn)呢?Pet類很容易。您已經(jīng)看見(jiàn)如何實(shí)現(xiàn)它了:
// class Pet
function Pet(name)
{
this.getName = function()
{
return name;
}
this.setName = function(newName)
{
name = newName;
}
}
Pet.prototype.toString = function()
{
return "This pet's name is: " + this.getName();
}
// end of class Pet
var parrotty = new Pet("Parrotty the Parrot");
alert(parrotty);
現(xiàn)在,如何創(chuàng)建從Pet派生的類Dog呢?在圖9種可以看到,Dog有另一個(gè)屬性breed,它改寫了Pet的toString方法(注意,JavaScript的約定是方法和屬性的名稱使用camel大小寫,而不是在C#中建議的Pascal大小寫)。圖10顯示如何這樣做。
Figure 10 從 Pet 類派生
// class Dog : Pet
// public Dog(String name, String breed)
function Dog(name, breed)
{
// think Dog: base(name)
Pet.call(this, name);
this.getBreed = function()
{
return breed;
}
// Breed doesn't change, obviously! It's read only.
// this.setBreed = function(newBreed){breed = newBreed;}
}
// this makes Dog.prototype inherits from Pet.prototype
Dog.prototype = new Pet();
// remember that Pet.prototype.constructor
// point to Pet. We want out Dog instances' constructor
// to point to Dog.
Dog.prototype.constructor = Dog;
// Now we override Pet.prototype.toString
Dog.prototype.toString = function()
{
return "This dog's name is: " + this.getName() + " , and its breed " +
"is: " + this.getBreed();
};
//end of class Dog
var dog = new Dog("Buddy", "Greed Dane");
// test the new toStirng()
alert(dog);
// Testing instanceof (similar to the is operator)
// (dog is Dog)? yes
alert(dog instanceof Dog);
// (dog is Pet)? yes
alert(dog instanceof Pet);
// (dog is Object)? yes
alert(dog instanceof Object);
所使用的原型 — 替換技巧正確設(shè)置了原型鏈,因此假如使用C#,測(cè)試的實(shí)例將按預(yù)期運(yùn)行。而且特權(quán)方法仍然會(huì)按預(yù)期運(yùn)行。 下一節(jié):模擬命名空間 |
|
|