Classes

出自OpenFace

(重定向自25.Classes)
跳转到: 导航, 搜索

Prev                                                                        Next

                               第二十章 类

                               第四部分 进级概念


  本章以我们的类系统的基本特征的简明概要开始,以怎样有效的使用LZX的评论结尾。

  本章解释了OpenLaszlo 应用中面向对象编程的基本概念,特别是<class>标签。


目录

概况

  类是LZX编程的核心。根据你个人情况,你可以参阅几种OpenLaszlo文档以学习怎样在你的应用中有效的使用类。

  为了找到在 OpenLaszlo应用中使用类的感觉,你可以先阅读类的介绍。那是开始学习的最佳资料,尤其是你从未学习过面向对象编程。

  你在阅读的本章包含对Laszlo的类的更简明的说明和LZX相关的面向对象系统的诠释。特别的,本章假定你已掌握了指南中的概念。我们会忽略怎样创建和继承类以及怎样设计LZX支持的快速应用开发的探究。

  第24章,类的继承为更多的开发者增加经验。它提供更先进的技术。

class语法摘要

  在最简单的形式中,类可以作为宏用于,在复杂的结构中简化为一个单独的标签。下例定义了一个square类,并进行了两次实例化。

Example 20.1. Defining a new tag

<canvas height="20">
 <class name="square"  extends="view"/>
 <square width="20" height="20" bgcolor="red"/>
 <square x="30" width="20" height="20" bgcolor="red"/>
</canvas>

  该例等价于下例,但更简短更易理解和掌握。

Example 20. 没有class标签

<canvas height="20">
 <view width="20" height="20" bgcolor="red"/>
 <view x="30" width="20" height="20" bgcolor="red"/>
</canvas>

  除此之外,第一个例子中定义的类可以通过使用<library> and <include>标签移动到一个单独的文件中。

Example 20.3 在library定义标签

<canvas height="20">
 <include href="square.lzx"/>
 <square width="20" height="20" bgcolor="red"/>
 <square x="30" width="20" height="20" bgcolor="red"/>
</canvas>
<library>
 <class name="square" />
</library>

属性

  类的属性对每个实例都是默认的属性。实例可以通过提供自己的属性重写这些属性。

Example 20.4 属性复制

<canvas height="20">
 <include href="square.lzx"/>
 <square />
 <square x="30" bgcolor="green"/>
</canvas>

属性

  若一个类的定义中包含子节点,则这些子节点被类的实例继承。

Example 20.5

<canvas height="30">
  <class name="myframe" >
      <view x="2" y="2" width="16" height="16" bgcolor="blue"/>
  </class>
  <myframe bgcolor="red"/>
  <myframe x="30" bgcolor="red"/>
</canvas>


Example 20.6

<canvas height="200" width="200">
 <class name="myframe" extends="view">
    <view x="5" y="5" width="${parent.width-10}" height="${parent.height-10}" bgcolor="blue"/>
 </class>
 <myframe width="40" height="40" bgcolor="red"/>
</canvas>

  这里的extends属性不是必须的。默认的基类是LzView类。

  创建一个myframe实例

函数

  类中定义的方法对类的实例都是可用的,并且重写的超类方法可以通过super关键字调用。

  与很多面向对象系统不同,Laszlo允许在类的实例中重写类的方法。

Text 类

  The <text> and <inputtext>标签在类的构建中它们持有的文本内容是唯一的。

Example 20.7. 创建text类

<canvas height="50">
 <simplelayout/>
 <inputtext>plain text</inputtext>
 <text>text</text>
</canvas>

  <inputtext>标签可能包含text字符.

  文本内容作为类的text属性是可用的.

Example 20.8. 继承text类

<canvas height="50">
 <simplelayout/>
 <class name="mytext" extends="text"/>
 <class name="myinputtext" extends="inputtext"/>
 <myinputtext>plain text</myinputtext>
 <mytext> text</mytext>
</canvas>

布局

  类的内部结构对它的分级的子节点通常是不可见的。默认情况下,出现在类内部的实例使子节点成为类的顶层实例。这对容器类通常是不合理的。

Example 20.9. 类里缺省布局

<canvas height="50">
 <class name="myframe" extends="view">
   <view x="5" y="5" width="${parent.width-10}" height="${parent.height-10}" bgcolor="#FFFFCC" />
 </class>
 <myframe width="220" height="20" bgcolor="red">
   <text>This is some text</text>
 </myframe>
</canvas>

  已知错误: 属性defaultplacement的值必须是双引用的。("")

Example 20.10.

<canvas height="50">
 <class name="myframe" extends="view">
   <attribute name="defaultplacement" value="'iv'"/>
   <view x="5" y="5" width="${parent.width-10}" name='iv' height="${parent.height-10}" bgcolor="#FFFFCC"/>
 </class> 
 <myframe width="220" height="50" bgcolor="red">
   <text>This is some text</text>
 </myframe>
</canvas>

类里定义约束

  约束使一个属性值与其他属性的值关联的一般机制,如第19章所述。

  在类的定义时使用约束要谨慎。这依赖于你用于指定约束的语法,你可能会遇到以下问题:

  由类的所有实例共享的单一的实体,或者

  类的每个实例的唯一实体

创建共享对象

  创建共享对象

  类的定义中可以使用以下形式:   value="[]"   value="new Array()"   value="{}"   value="new Object()"

  你会得到一个由所有实例共享的单一数组或对象

为每个实例创建唯一的对象

  在类的定义中,可以使用以下形式:   value="${[]}"   value="${new Array()}"   value="${{}}"   value="${new Object()}"

  每个实例都会获取自己的数组和对象。

  注意${}等价于 $always{}, 但由于每部的表达式没有依赖,它也   等价于$once{}。 因此也许使用$once{}语法更好。这也可以提高可读性。


对名称进行引用

  不管怎样实例类,你都可以给view命名,并象下面那样访问它:

Example 20.11. 对名称进行处理

<canvas>
 <script>
   var foo = new LzView(canvas, {width:50,height:50,x:50,y:100,bgcolor:0,name:"myview"});
 </script> 
 <text>Make window red
   <handler name="oninit">
     var nameOfView = "myview";
     canvas[nameOfView].setAttribute('bgcolor', 0xff0000);
   </handler>
 </text>
</canvas>

原型语言

  LZX是基于原型的语言:任何属性都可以附属于类的 定义或类的实例。这在有很多一次性行为对象的UI程序中是很方便的。这对原型和程序开发的扩展新颖的分解创建可能性也很方便。

  下面的两个XML   文件完全是LZX程序。每个都定义了名为myview的视图,它们都包含一个名为f的方法。在每个应用中通过返回100评价方法f。

Example 20.12. 函数

<canvas>
 <view id="myview">
   <method name="f">return 100;</method>
 </view>
</canvas>

Example 20.13 类里的函数

<canvas>
 <class name="myclass">
   <method name="f">return 100;</method>
 </view>
 
 <myclass id="myview"/>
</canvas>


实例开发

  以上两个程序从提供的开发策略的角度而言是等价的。


全局变量

  一次实例技术是使用全局变量。通常开发和调试存储全局变量状态的程序比使用局部变量,session,用户对象的程序更容易。这样可以避免通过API调用的环环相扣的情况,而且可以容易的找到并操作状态。

  最后你可以将全局变量转换成状态对象的成员,这种转变是相对简单的,特别是你已经用这种知识写了程序。这种技术比其他所有的程序转换时维持状态和写额外的访问更廉价。这对于你打算转换程序的原则是特别的情况。你可以优化要转化的程序的顺序。在一次实例开发的全局变量中,整个程序是一个实例。基于原型的程序支持不依赖全局变量的其他途径。 用基于原型的程序,你可以增加功能性并和对象的实例进行交互,在另一个同名实例被调用时把它它的成员转变成类。这样可以避免程序的 缺陷,不成熟性,过早产生无显著特点的行为的地方,必须在框架层重写,很难给出调试的原因和花费,而不是在具体的实例层。从两个例子比一个更容易归纳出特点。

  在没有原型的语言中,你可以通过执行"singleton"类为实例驱动开发提供这种策略。原型简便的取代了开发中必须的中间部分,减少行数等。这在用户实例存在很多一次性可视对象的程序时特别有用。使用单独的类会明显的增加程序的规模,但你想自由快速的把它们加到类中。一门语言中原型也支持类。

  一次实例开发类似于测试驱动开发,但有区别。在测试驱动开发中,你增加功能性的测试细节来解决增长的测试问题。在一次实例开发中,你增加功能性的实例细节给实例,从而总结。两者都是先执行具体例子,然后由它们进行归纳。

实例替代原则

  在LZX中,类是用户定义的XML标签,它和非XML语言中类的定义是等价的。

  理解LZX类定义的时候,你可以发现以下有用的原则:

  实例置换原则:类的实例可以由实例的定义取代, 而不改变程序。

  文章开始的两个程序说明了实例置换原则。

  实例置换原则可以应用于语义学层面,或者语法级。对语义学,它意思是一个成员可以附属于   类或它的实例。对语法层,意味着定义类成员和实例。


LZX和其它语言的比较

  很多基于原型的语言不遵从实例置换原则,或许因为它们没有类,或许类和实例的定义不是平行的。JavaScript 1.0版本也是基于原型的语言,但是缺少类作为实体,并且缺少分级语法,Java, C++, 和 LZX使用定义类成员。JavaScript 2.0,JScript.NET, 和Python 有类定义语法,但不使用想通的语法定义实例成员。例如:对比下面的两个于lzx程序平行的Python程序:

 myobject = object()
 myobject.f = lambda f: 100


class MyClass(object):
 def f():
   return 100
myobject = MyClass()

  这种实例置换原则的版本使得类看起来象函数或宏。类。函数。宏定义都是可重用的抽象程序结构的机制。

  有些语言隐藏了这一点,因为它们缺少细节和普通例子的机制.例如实例置换原则只对有原型和类的语言有意义;在诸如缺少匿名函数表现中间级的C++或Java等语言中顺序的陈述函数定义的出处是很难的。

                            Home

Prev                                                                        Next