Javascript面向对象编程 之 modello

来源:互联网 发布:数据分析师知识体系 编辑:程序博客网 时间:2024/06/03 22:39

来源:http://liuxiaoqing007.spaces.live.com/blog/cns!e3179609ba91ca44!158.entry

    在写这个文章之前,首先公布几个网站,
 
  1. modello的官方站点: http://modello.sourceforge.net/ 几乎没有什么,界面很简洁,介绍了modello的主要用法,提供了下载的地址。是ajaxwing的 sourceforge.net 空间。除了下载文件我看不出还有其他的用处。
  2. ajaxwing官方站点:http://www.ajaxwing.com/ modello的中文官方站点,并且拥有了一个不错的基于 modello 和 ajax 技术的代码着色函数库,还有不少作者的原创文章,也是我的启蒙站点。
  3. prototype.js的官方站点: http://prototype.conio.net/ 现在的很多项目使用的都是这个函数库,我就是通过这个库进而了解到modello的,不过由于使用比较烦琐,所以我并没有采用该函数库,但是在阅读一些使用该库的代码时,还是要对其有一定的了解。

    至于qooxdoo的站点我就暂时不公开了,因为这个文章内没有涉及到其中的内容。

一、一些题外话,当前的几种技术

    作者长篇累牍的介绍了javascript的面向对象的原有做法,还有就是prototype.js函数库的用法,其目的是强调modello在面向对象的设计上更加“象”真正的面向对象语言,而且说可以和使用微软的Atlas编写的代码相媲美。我没有用过Atlas,所以无法给出比较,这样的比较也没有意义。不过在我个人看来,比较了modello.js、prototype.js、qooxdoo.js这几种javascript面向对象的解决方案来看,还是modello.js更胜一筹,而且据作者称还可以和prototype.js编写的代码相兼容,这个是一个很大的诱惑。而qooxdoo.js所使用的面向对象方法比较蹩脚,有兴趣的可以看看,不太象正常的代码,不过为了能够研究qooxdoo框架,我也会讲解其中的用法。

二、Javascript AJAX 面向对象

    自打面向对象的编程语言出现以来,人们思考问题的方式也发生了根本的转变,变得简单而更加“象”这个世界。javascript作为一种轻量级的网页脚本语言,虽然支持对象,但是在面向对象的编程上做的并不够好。但是人们一直以来也并没有抱怨,因为我们用javascript只是编写一些代码的片断,来判断页面上输入的值是否符合要求,或者显示一些动态的效果之类,代码通常很短。

    但是自从ajax这个技术出现以来,javascript就担负着重大的历史使命,因为它几乎是唯一一种可以在各种浏览器上运行的在本地运行的脚本程序(别挑我这句话的毛病,大家明白意思就行,不用举反例),而ajax的技术就是javascript和xml技术的结合。在ajax程序当中大量的使用javascript这让程序的编写成为一件极其痛苦的事情,这就好像使用c语言来编写一个大型的管理系统一样。并非无法完成,而是没有把研究的主要方向放在真正的系统分析和设计上,而是花在了对于程序语言的运用上。

三、进入正题,HelloWord!

    看别人写书先写个Helloword的例子,我也弄一个

   //创建一个类 

   var Test = Class.create();

  //编写类的内容
   Test.construct = function() {
     var _str = "";//私有变量(通常以"_"开头)
     this.str = "Public Hello Word !";//共有变量;

     //构造函数
     this.initialize = function(str) {
       _str = str;
     }

     //set函数

     this.setStr = function(str) {
       _str = str;
     }

     //get函数

     this.getStr = function() {
       return _str;
     }

   }

  //创建类的实体
   var t = new Test("Hello word !");   
   alert(t.str);//测试Public 变量
   alert(t.getStr());//测试get函数

四、如何执行本代码?

    在文本文件当中输入以下内容,另存为html文件,把modello.js文件放到与该文件同目录下,执行html文件即可

<html>
 <head>
  <title>HelloWord</title>

   <script type="text/javascript" src="modello.js"></script>

 </head>
 <body>


  <script language="javascript">
   var Test = Class.create();
   Test.construct = function() {
     var _str = "";
     this.str = "Public Hello Word !";
     this.initialize = function(str) {
       _str = str;
     }

     this.setStr = function(str) {
       _str = str;
     }

     this.getStr = function() {
       return _str;
     }

   }


   var t = new Test("Hello word !");
   alert(t.str);
   alert(t.getStr());

  </script>
 </body>
</html>

    其中<script ></script>中间为javascript的代码内容,以后除非特殊情况内容我就不会再编写html文本,我会直接发布javascript内容代码。

    很简单的创建类,创建类对象的例子,如果你还不明白什么是面向对象,那么无法理解我也没有办法,只有回去好好补补了;如果学过至少一种面向对象的语言,我想我不用多说,代码的含义也就很清楚了。

    在下次的文章当中我会讲解modello当中更多的面向对象的应用,体会javascript面向对象编程的强大功能。

 

2006/5/5

Javascript面向对象编程 之 modello(2、面向对象详细介绍)

取自http://www.ajaxwing.com/index.php?id=2

下面介绍 Modello 的使用方法:

1,定义一个类

Point = Class.create();/*  创建一个类。用过 prototype.js 的人觉得很熟悉吧;)*/
2,注册一个类

Point.register("Modello.Point");

/*  这里"Modello"是命名空间,"Point"是类名,之间用"."分隔  如果注册成功,  Point.namespace 等于 "Modello",Point.classname 等于 "Point"。  如果失败 Modello 会抛出一个异常,说明失败原因。*/

Point.register("Point"); // 这里使用默认的命名空间 "std"

Class.register(Point, "Point"); // 使用 Class 的 register 方法
3,获取已注册的类

P = Class.get("Modello.Point");

P = Class.get("Point"); // 这里使用默认的命名空间 "std"
4,使用继承

ZPoint = Class.create(Point); // ZPoint 继承 Point

ZPoint = Class.create("Modello.Point"); // 继承已注册的类

ZPoint = Class.create(Point1, Point2[, ...]);

/*  多继承。参数中的类也可以用已注册的类名来代替*/

/*  继承关系:  Point.subclasses 内容为 [ ZPoint ]  ZPoint.superclasses 内容为 [ Point ]*/
5,定义类的静态成员

Point.count = 0;

Point.add = function(x, y) { 

   return x + y;

}
6,定义类的构造函数

Point.construct = function($self, $class) { 

    // 用 "var" 来定义私有成员    var _name = "";

    var _getName = function () {

        return _name;

    } 

    // 用 "this" 来定义公有成员

    this.x = 0;

    this.y = 0;

    this.initialize = function (x, y) { // 初始化函数

        this.x = x;

        this.y = y;

        $class.count += 1; // 访问静态成员

     // 公有方法访问私有私有属性

    this.setName = function (name) {

        _name = name;

    }

     this.getName = function () {

        return _getName();

    }

     this.toString = function () {

        return "Point(" + this.x + ", " + this.y + ")";

    }

    // 注意:initialize 和 toString 方法只有定义成公有成员才生效

     this.add = function() {

        // 调用静态方法,使用构造函数传入的 $class

        return $class.add(this.x, this.y);

    }

 }

 ZPoint.construct = function($self, $class) {

     this.z = 0; // this.x, this.y 继承自 Point

     // 重载 Point 的初始化函数

    this.initialize = function (x, y, z) {

        this.z = z;

        // 调用第一个父类的初始化函数,

        // 第二个父类是 $self.super1,如此类推。

        // 注意:这里使用的是构造函数传入的 $self 变量

        $self.super0.initialize.call(this, x, y);

        // 调用父类的任何方法都可以使用这种方式,但只限于父类的公有方法

    }

     // 重载 Point 的 toString 方法

    this.toString = function () {

        return "Point(" + this.x + ", " + this.y + 

              ", " + this.z + ")";

    }

 }

  // 连写技巧

Class.create().register("Modello.Point").construct = function($self, $class) {    // ...}
7,创建类的实例

// 两种方法:

new 和 createpoint = new Point(1, 2);

point = Point.create(1, 2);

point = Class.get("Modello.Point").create(1, 2);

zpoint = new ZPoint(1, 2, 3);
8,类型鉴别

ZPoint.subclassOf(Point); // 返回

truepoint.instanceOf(Point); // 返回

truepoint.isA(Point); // 返回

truezpoint.isA(Point); // 返回

truezpoint.instanceOf(Point); // 返回 false

// 上面的类均可替换成已注册的类名
以上就是 Modello 提供的全部功能。下面说说使用 Modello 的注意事项和建议:

在使用继承时,传入的父类可以是使用 prototype.js 方式定义的类或者 JavaScript 方式定义的构造函数
类实际上也是一个函数,普通的 prototype 的继承方式同样适用在用 Modello 定义的类中
类可以不注册,这种类叫做匿名类,不能通过 Class.get 方法获取
如果定义类构造函数时,像上面例子那样提供了 $self, $class 两个参数,Modello 会在创建实例时将实例本身传给 $self,将类本身传给 $class。$self 一般在访问父类成员时才使用,$class 一般在访问静态成员时才使用。虽然 $self和$class 功能很强大,但不建议你在其它场合使用,除非你已经读懂 Modello 的源代码,并且的确有特殊需求。更加不要尝试使用 $self 代替 this,这样可能会给你带来麻烦
子类无法访问父类的私有成员,静态方法中无法访问私有成员
Modello 中私有成员的名称没有特别限制,不过用"_"开始是一个好习惯
Modello 不支持保护(protected)成员,如果你想父类成员可以被子类访问,则必须将父类成员定义为公有。你也可以参考 "this._property" 这样的命名方式来表示保护成员:)
尽量将一些辅助性的计算复杂度大的方法定义成静态成员,这样可以提高运行效率
使用 Modello 的继承和类型鉴别可以实现基本的接口(interface)功能,你已经发现这一点了吧;)
使用多继承的时候,左边的父类优先级高于右边的父类。也就是说假如多个父类定义了同一个方法,最左边的父类定义的方法最终被继承

原创粉丝点击