一个继承机制可以有多简单?
以下是一个最简单的实现继承基类属性和方法的示例:
<script type="text/javascript">
//声明继承自哪一个基类
Function.prototype.extend = function(baseClass){
this.baseClass = baseClass;
}
//初始化基类的属性(其实这个函数才具体实现"继承"基类属性和方法)
Function.prototype.initializeBase = function(){
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
//定义一个基类
function MyBase(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
//定义一个扩展类
function MyClass(name,age){
MyClass.initializeBase(this,[name]);//初始化基类
this.age = age;
this.showAge = function(){
alert(this.age);
}
}
MyClass.extend(MyBase);//声明继承自MyBase
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
这里对initializeBase方法的注释是"初始化基类",但其实initializeBase的更重要的功能是"继承"的具体实现.没有这个方法的调用,即使你用extend方法声明过了继承自哪一个类了,但是基类的属性在派生类中还是没有得到真正的"赋予".//声明继承自哪一个基类
Function.prototype.extend = function(baseClass){
this.baseClass = baseClass;
}
//初始化基类的属性(其实这个函数才具体实现"继承"基类属性和方法)
Function.prototype.initializeBase = function(){
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
//定义一个基类
function MyBase(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
//定义一个扩展类
function MyClass(name,age){
MyClass.initializeBase(this,[name]);//初始化基类
this.age = age;
this.showAge = function(){
alert(this.age);
}
}
MyClass.extend(MyBase);//声明继承自MyBase
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
这种类的设计方式是依赖于JavaScript的动态属性扩展能力而实现的,因此这种方式的继承机制,不是在于"基类"与"派生类"之间的属性/方法继承,"派生类"其实与"基类"没关系,"派生类"只是通过extend而知道了自己的基类,具体的基类的属性和方法,要由被实例化的对象自己去基类的构造函数那获取.
这种继承实现方式如果非要用一个比喻来形容的话,就仿佛是...应该是你的老板A直接付你工资,但是他不,他不乐意(我靠!).他说某老板B欠他钱,他有凭据(A.extend(B)),他要求你去找B要去(A.initializeBase(this)),幸好,B还算有信,二话不说给了你钱(B.apply(self,[...]).
:)
真正的派生类与基类之间继承
要实现真正的,派生类通过extend方法就完全获得基类的属性和方法,则必须依靠prototype,这也是类定义的两种方法之一.具体请看如下示例:
<script type="text/javascript">
Function.prototype.extend = function(baseClass){
for(var ptototypeName in baseClass.prototype){
if(typeof(this.prototype[ptototypeName]) === 'undefined'){
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
function MyBase(name){
}
MyBase.prototype = {
name: null,
showName: function(){
alert(this.name);
}
}
function MyClass(name,age){
this.name = name;
this.age = age;
}
MyClass.prototype = {
age: null,
showAge: function(){
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
此时,MyClass在extend的时候,就从MyBase那完全获取了属性和方法(这些属性和方法定义在prototype上).因此,可以直接通过prototype的内建功能把属性和方法赋予MyClass所创建的实例上了.Function.prototype.extend = function(baseClass){
for(var ptototypeName in baseClass.prototype){
if(typeof(this.prototype[ptototypeName]) === 'undefined'){
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
function MyBase(name){
}
MyBase.prototype = {
name: null,
showName: function(){
alert(this.name);
}
}
function MyClass(name,age){
this.name = name;
this.age = age;
}
MyClass.prototype = {
age: null,
showAge: function(){
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
还是那个比喻...你的老板A幡然悔悟,他强烈要求即时付你工钱,决不让你自己去讨要第三方欠他的债...因此你就不同到B那跑一趟了,尽管B这人还是不错的...
继承机制的完美实现
其实就是把上面的两种方法结合起来...
如下:
<script type="text/javascript">
Function.prototype.extend = function(baseClass){
this.baseClass = baseClass;
for(var ptototypeName in baseClass.prototype){
if(typeof(this.prototype[ptototypeName]) === 'undefined'){
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
Function.prototype.initializeBase = function(){
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
function MyBase(name,sex){
this.name = name;
this.sex = !!sex;
this.showSex = function(){
if(!!sex){
alert("男");
}else{
alert("女");
}
}
}
MyBase.prototype = {
name: null,
showName: function(){
alert(this.name);
}
}
function MyClass(name,age,sex){
MyClass.initializeBase(this,[name,sex]);
this.age = age;
}
MyClass.prototype = {
age: null,
showAge: function(){
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25,true);
m.showName();
m.showAge();
m.showSex();
</script>
现在,你的老板A又改了策略.他顾及舆论的压力,直接付了你一点钱,另外一部分,还是要你去找欠他款的B要...ok,你可以去见B了,B还是很讲信用滴~~~当然你要祈祷没有欠B款的C,否则你会去找C的...一直......
Function.prototype.extend = function(baseClass){
this.baseClass = baseClass;
for(var ptototypeName in baseClass.prototype){
if(typeof(this.prototype[ptototypeName]) === 'undefined'){
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
Function.prototype.initializeBase = function(){
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
function MyBase(name,sex){
this.name = name;
this.sex = !!sex;
this.showSex = function(){
if(!!sex){
alert("男");
}else{
alert("女");
}
}
}
MyBase.prototype = {
name: null,
showName: function(){
alert(this.name);
}
}
function MyClass(name,age,sex){
MyClass.initializeBase(this,[name,sex]);
this.age = age;
}
MyClass.prototype = {
age: null,
showAge: function(){
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25,true);
m.showName();
m.showAge();
m.showSex();
</script>