JavaScript面向对象编程:类定义、继承、接口实现

在此之前,刚接触JS面向对象的童鞋可先阅读一下这两个系列的文章:Javascript面向对象编程 和 JavaScript继承详解

我也了解jQuery、Prototype这几个框架对面向对象的实现方式,就我个人比较的结果,最后发现还是ExtJS的实现最优雅,用那种方式开发出来的代码可读性更好(个人觉得)。可先参阅 ExtJS的面向对象相关文档

如果项目足够庞大的话,可以直接把ExtJS的实现copy出来用。但是,对于一般的项目的来说,ExtJS的面向对象的东西实现得过于多了点,功能过于臃肿了点,比如我就不希望实现静态成员这个功能,不希望实现mixins等这些很少用的功能。因为静态成员无非就是一些用类名称直接调用的函数,其实从实际意义上来说完全可以写成挂到某命名空间下的函数集(类名称相当于一个命名空间),这是其一,其二是我们在开发中有多少情况需要静态成员?很少吧。所以不必实现这个功能。


所以我简单实现了一下ExtJS那种面向对象方式,下面先贴怎么使用这种方式进行面向对象程序设计的例子,然后再贴出实现代码。

<!DOCTYPE html>
<html>
<head>
<title>class test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="define.js"></script>
</head>
<body>

<div style="width:500px;margin:0 auto;">
	<div style="color:#0000ff;">输出信息:</div>
	<div id="log" class="result"></div>
</div>

<script type="text/javascript">
function trace(msg){
	document.getElementById('log').innerHTML += msg+'<br/>';
}

try{
//* 删掉一个反斜线则恢复注释,相反,两个反斜线就是让下面这块代码可以运行
//类的定义
var People = N.define({
	constructor: function(name){ //类的构造器(构造函数)
		this.name = name; //类的成员
		this.oneObj = {kkk: 5};
	},
	hometown: '北京',
	testObj: {abc:1}, //这也是类的成员,请留意构造器里定义的成员和构造器外定义的成员的共享情况
	getName: function(){ //类的方法
		trace(this.name);
	},
	setHometown: function(hometown){
		this.hometown = hometown;
		this.testObj.abc = 2;
		this.oneObj.kkk = 6;
	},
	getHometown: function(){
		trace(this.hometown);
		trace(this.testObj.abc);
		trace(this.oneObj.kkk);
	}
});
var lm = new People('李明');
lm.getName();
lm.setHometown('上海');
lm.getHometown();

var xh = new People('肖华');
xh.getName();
xh.getHometown();
// */

/*
//类的继承
var People = N.define({
	constructor: function(name){
		this.name = name;
	},
	getName: function(){
		trace(this.name);
	},
	move: function(){
		trace(this.name+' 动一动。。');
	}
});
var Woman = N.define({
	extend: People, //继承哪个父类
	constructor: function(name, friend){
		this.friend = friend;
	},
	//方法重载
	getName: function(){
		trace('我的名字叫'+this.name);
	},
	getFriend: function(){
		trace('我的朋友是'+this.friend);
	}
});
var xh = new Woman('李小花', 'Lily');
xh.getName();
xh.getFriend();
xh.move(); //父类方法

var hmm = new Woman('韩梅梅', '李雷');
hmm.getName();
hmm.getFriend();
// */

/*
//接口的实现
var InterfA = {getName:1}; //接口就是一个个纯对象
var InterfB = {run:1};
var Woman = N.define({
	implement: [InterfA], //[InterfA, InterfB], //要实现的接口,把所有接口放到一个数组里
	constructor: function(name, friend){
		this.name = name;
		this.friend = friend;
	},
	getName: function(){
		trace('我的名字叫'+this.name);
	},
	getFriend: function(){
		trace('我的朋友是'+this.friend);
	}
});
var xh = new Woman('李小花', 'Lily');
xh.getName();
xh.getFriend();
// */

/*d//
//类的继承,实现接口
var People = N.define({
	constructor: function(name){
		this.name = name;
	},
	getName: function(){
		trace(this.name);
	},
	move: function(){
		trace(this.name+' 动一动。。');
	}
});
var InterfA = {getName:1};
var InterfB = {run:1};
var Woman = N.define({
	extend: People,
	implement: [InterfA, InterfB],
	constructor: function(name, friend){
		this.friend = friend;
	},
	//方法重载
	getName: function(){
		trace('我的名字叫'+this.name);
		//this.$super.getName();
	},
	run: function(){
		this.$super.move(); //在子类里调用父类的方法
		trace(this.name+' is running and running...');
	},
	getFriend: function(){
		trace('我的朋友是'+this.friend);
	}
});
var xh = new Woman('李小花', 'Lily');
xh.getName();
xh.getFriend();
xh.move(); //父类方法

var hmm = new Woman('韩梅梅', '李雷');
hmm.getName();
hmm.getFriend();
hmm.run();

var lm = new People('李明');
lm.getName();
//d*/

}catch(e){alert(e)}
</script>
</body>
</html>


实现这种面向对象方式的JS代码:define.js文件

/**
 * @fileoverview 类的定义,继承,接口实现
 */
var N = {};

N.define = function(classInfo){
    function F(){}
    if( typeof classInfo !== 'object' ){
        return F;
    }

    var constructor = classInfo.constructor || F,
        superclass = classInfo.extend,
        implement = classInfo.implement,
        newclass,
        prototype,
        k;
    
    //!!!继承父类
    if( superclass ){
        var superPrototype = superclass.prototype;

        newclass = function(){
            var _this = this;
            this.$super = {};
            for(k in superPrototype){
                if( typeof superPrototype[k] === 'function' ){
                    this.$super[k] = (function(fn){
                        return function(){
                            return fn.apply(_this, arguments);
                        }
                    })(superPrototype[k]);
                }
            }
            superclass.apply(this, arguments);
            constructor.apply(this, arguments);
        };
        
        F.prototype = superPrototype;
        newclass.prototype = new F();
        //newclass.prototype.constructor = newclass;

        delete classInfo.extend;

    }else{
        newclass = constructor;
    }

    prototype = newclass.prototype;
    delete classInfo.constructor;
    delete classInfo.implement;

    //!!!添加公共成员(方法、属性),不支持私有成员或保护成员
    for(k in classInfo){
        if(classInfo.hasOwnProperty(k)) {
            prototype[k] = classInfo[k];
        }
    }
    
    //设置原型链的constructor
    prototype.constructor = newclass;

    //!!!实现接口的话,检查是否实现所有接口方法
    if( implement ){
        for(var i=implement.length, interf; i--;){
            interf = implement[i];
            if(typeof interf !== 'object'){
                //implement语句错误:参数必须为object类型
                throw 'An interface must be object type!';
            }
            
            for(k in interf){
                if( typeof prototype[k]!=='function' && interf.hasOwnProperty(k) ){
                    throw 'NOT implement the function [' + k + ']!';
                }
            }
        }
    }
    
    return newclass;
};

接口继承的话,直接用对象的浅拷贝就能实现接口继承。

请各位童鞋提改进意见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值