日期:2014-05-16  浏览次数:20366 次

Javascript面向对象基础以及接口和继承类的实现
转http://developer.51cto.com/art/200901/104775.htm
在开始设计模式的书写之前,有必要对Javascript面向对象的概念先做个介绍,那么这篇文章就以面向对象基础作为起点吧。

理论知识

1. 首先Javascript是弱类型语言,它定义变量时不必声明类型,如var Person = new Person(),它的变量类型为“var”,现在的C# 3.0也引进了这种匿名类型的概念,弱类型的变量产生了极大的灵活性,因为Javascript会根据需要来进行类型转换。所以这也决定了它采用了晚绑定的方法,即在运行后才知道变量的类型;

2. 面向对象概念不必多说,封装,继承,多态;

3. Javascript对象的类型主要分为三种:本地对象,如String,Array,Date等;内置对象,如Global,Math等;宿主对象,是指传统面向对象程序设计中的作用域,如公有,保护,私有,静态等等。

主要内容

1. 现在让我们来看看Javascript怎样创建对象的:

<script type="text/javascript">
        function Man(){ }
        Man.prototype.getNickName=function()
        {
            return '爱在Cookies';
        }
        var man = new Man();
        alert(man.getNickName());
    </script>

这样就创建了最简单的类和对象,其中我们可以把function Man() {} 看作是Man类的构造函数,getNickName()看作是Man类的方法,准确说可以“当作”是Man类的公共方法;为什么要说是当作呢?那是因为其实Javascript实际上并没有一个私有共有的划分,因此开发者们自己指定了这样的规约,那么规约是什么样的呢?我这里把Man类的清单完整地列出来:

<script type="text/javascript">
      function Man()
      {
          // 私有静态属性
          var sex='男';
          //私有静态方法
          function checkSex()
          {
              return (sex=='男');
          }
        //私有方法
          this._getSex=function()
          {
             if(checkSex())
             {
                 return '男';
             }else
             {
                 return '女';
             }
          }
          //私有方法
          this.getFirstName=function()
          {
              return '陈';
          }
          //私有方法
          this.getLastName=function()
          {
              return '顶强';
          }
      }
        //公共方法      
       Man.prototype.getNickName=function()
       {
           return '爱在Cookies';
       }
        //公共方法
        Man.prototype.getFullName=function()
        {
            return this.getFirstName+this.getLastName;
        }
         //公共方法
        Man.prototype.getSex=function()
        {
            return this._getSex();
        }
        //公共静态方法         
        Man.say=function()
        {
            return 'Happy new Year!';
        }
    </script>

这样的类是否看起来和传统的类很相似了呢?
2.接下来这个是本篇的一个重点,就是用Javascript如何设计一个接口,然后让类继承于它。

首先,先让我们看传统的C#语言是如何设计接口的吧:
public interface Person
{
    string GetName();
    void SetName(string name);
}
public class Man : Person
{
    private string _name; 

    public string GetName()
    {
        return _name;
    }
    public void SetName(string name)
    {
        _name = name;
    }
} 

接口中可以声明属性、方法、事件和类型(Structure),(但不能声明变量),但是并不能设置这些成员的具体值,也就是说,只能定义,不能给它里面定义的东西赋值,而接口作为它的继承类或者派生类的规约,继承类或者它的派生类能够共同完成接口属性、方法、事件和类型的具体实现,因为这里GetName(),SetName(),不管是方法名还是属性调用顺序上都是要保持一致的;

那么有了这样的一个基于接口的思想,我们设计Javascript的接口类的时候也需要考虑到这个规范。我先从主JS文件调用端开始说起:
 <script type="text/javascript">
     function Man()
    {
        this.name = "";
        Interface.registerImplements(this, Person);
    }
    Man.prototype.getName = function() {
        return this.name;
    };
    Man.prototype.setName = function(name) {
        this.name = name;
    };
    </script>

其中Interface类是稍后要说的接口类,第一个参数"Person"是接口类的名称,第二个参数是个二维数组,"getName"是接口方法的名称,"0"是该方法所带的参数个数(因为Javascript是弱语言,所以类型是不确定的,所以只要记住参数个数就好,"0"可以省略不写),"setName"同理。这样一个接口定义好了。怎样使用它呢?
看到Man的构造函数里面包含

Interface.registerImplements(this, Person);

它是用来将实例化的this对象继承于Person接口,然后继承类对接口的方法进行实现。

代码看起来是不是很清晰和简单呢,那么现在要开始介绍真正的核心代码Interface.js了:

先看Interface的构造函数部分

 <script type="text/javascript">

         function  Interface(name,methods)
         {
               if(arguments.length!=2)
               {
                   throw new Error("接口构造函数含" + arguments.length + "个参数, 但需要2个参数.");