PV3D-2.构建你的第一个应用_第1页
PV3D-2.构建你的第一个应用_第2页
PV3D-2.构建你的第一个应用_第3页
PV3D-2.构建你的第一个应用_第4页
PV3D-2.构建你的第一个应用_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

. 构建你的第一个应用 本章,我们将开始着手写第一行代码.那些刚进入oop的程序者可以从本章的oop简单介绍开始.如果已经很熟悉oop,可以跳过此段继续学习Papervision3D里的3D场景.明了后,我们可以开始写第一个基本工程!部分工程将被封装成默认的类,以后我们都会用到这些类.本章包含以下内容:l 面向类及对象编程介绍l 熟悉文档类/主程序文件l Papervision3D的3D组织的基础l 构建你第一个工程l 为书中的实例做准备面向类及对象编程介绍本书中,我们将着重使用Papervision3D类库.我们将写出用于Flash,FlexBuilder,Flash Builder中的类.若你是FlashIDE的开发者,这可能是你第一次写自己的类.面向对象的编程是本书的重要部分,本书给出了一些简短的介绍.若你已经很熟悉Flex,flash的oop编程,你可以直接阅读本章中的Papervision3D里的3D基本场景.若你是面向对象的新手也不必太担心本书仅用到了面向对象的基础.学习使用PaperVision3D进行面向对象编程可以让你对类更熟悉并且可能提高你对面向对象编程的兴趣.什么是类?实际上,他们只是一些的函数(方法)和变量(属性)组织在一个单独文件中,这被称为类的定义.一个类是创建新对象的设计.听起来有些模糊?其实你一直都在使用类.从FlashAPI里创建的每个Object都基于类.如Sprite,MovieClip,及TextField这些对象可能你都用过.实际上这些都是类.这些对象的设计及他们的类都在Flash中.首先看一下我们使用FlashAPI创建Sprite对象:var mySprite:Sprite = new Sprite();很熟悉?通过这些,你创建了一个 叫mySprite的Sprite类的对象.这叫做一个类的实例.内置的类与自定义的类没什么不同.Papervision3D是一个自定义类的集合.第一章说过如何来实例化一个Papervision3D里的DisplayObject3D类,var myObject3D:DisplayObject3D = new DisplayObject3D();一旦知道了如何使用类,就可以创建自己类了.创建自定义类 ActionScript类是存放于计算机上以.as结尾的文本文件,包括ActionScript脚本代码.这些代码就是前面所说的对象的设计.现在看看设计是什么样子:package public class ExampleClass public var myName:String = Paul; public function ExampleClass() public function returnMyName():String return My name is + myName; 第一行,是包(package)语句,紧随其后的是左大括号()和类下面的右大括号().包是组织类的一种方式,代表了存放类文件的目录.假设你创建了一个名为myPackage的目录并将FLA或源码文件存放在其中.为了访问此目录及里面的类,需要用目录名来定义包,如下:package myPackage .子目录的工作情况也一样.现在假设在myPackage目录下有一个名为subPackage的子目录.应该这样来定义子目录subPackage:package myPackage.subPackage . 如果你没有创建一个目录来组织你的类,可以使用默认包来代替相应的包名,(即不写包名)本书的所有例子都使用默认包.实际上,为了避免命名冲突,必须用包来组织众多的类.包定义之后,将看到类的定义,看起来如:public class ExampleClass .类的名字必须和类文件的名字一致.本例中,类文件必须存为ExampleClass.as.实际上,包是一种很好的类文件组织方式,可以让项目中每个类都有唯一的名字.避免命名冲突. 在class的前面有一个public,这是一个关键字用来表明项目中所有代码都可以访问此类.这个关键字被称为访问控制符.类的名字将被用来实例化类.像这样来实例化类:var classExample:ExampleClass = new ExampleClass();在类里定义的变量称其为类属性.类属性的数量不限.每个类属性均有访问控制符.本例中的访问控制符是public,表示所有的类都可以对其进行读写:var classExample:ExampleClass = new ExampleClass();classExample.myName = Jeff;这样便创建了一个类ExampleClass的实例.我们可以将属性myName由Paul改为Jeff.当一个属性声明为public,便可以这样操作.如果你想让属性只能在类中使用,需要将属性改为private:private var myName:String = Paul;这时执行之前的代码,会得到一个编译时错误.接着我们看到类中名为ExampleClass的方法.方法名与类名相同的方法被称为构造器(构造方法).public function ExampleClass()构造器的访问控制符均是public并且每当实例化类时就被自动调用.这表示构造器中的代码将被自动执行.类中其他的所有函数(function)都称为方法(method).public function returnMyName():String return My name is + myName;方法定义完后,你将发现一个冒号紧跟着一个数据类型.这是定义方法返回值的数据类型.你也可以在Flash的时间轴上这样定义方法,但这不是必须的.returnMyName()方法定义了返回值是字符串.如果你不想返回任何值,可以使用void作为返回类型:public function returnNothing():void /Do not return something我们只需为普通方法定义返回类型即可,构造器无返回值 类,及其属性和方法,都用访问控制符,用来确定对象的访问权限.到现在我们已经看到了关键字public,表示在任何地方都可以访问.当使用public时,必须注意到可能会造成类的混乱.可以用private关键字来避免这样情况,private将使属性或方法只能在本类内进行访问.其余两个常用的访问控制符是internal和ernal表示同一包内可以访问.protected表示属性或方法只能由子类访问.子类是oop继承的一部分,我们稍微将解释下. 只要属性或方法不准备在类外进行访问,最好将其设定为private.每当定义属性或方法时,你都应该确定下是否要在类外进行访问.继承有时想创建一个类,而此类和已存在的类又很相似,而你只是想添加一个新的方法.你可以拷贝已有的类,粘贴到新类中,再添加一个新的方法.然而这样做的效率很低.这时就有继承的用武之地了.继承是一种扩展已有类(称为父类或基类)的技术,从父类中继承的类称为子类.子类可以访问父类中所有非private的属性和方法.假设你准备用代码来创建一个汽车和一个摩托车.你可以直接写2个类,汽车和摩托车.但你很快就会注意到这2个类的方法和属性几乎都是重复的.比如2者都可以驾驶,都有属性:车轮数和速度.在抽象方式中,这些属性和方法都重复了,因为汽车和摩托车都是车辆.创建父类:车辆,汽车和摩托车都继承车辆便可以避免重复的代码.必要时,子类可以定义与父类不同的,自己专有的属性或方法.如:一汽车有4个轮子并可以在相反的方向驾驶.而摩托车有2个轮子,不能在相反的方向驾驶. 现在用2个简单类看一下继承是怎样完成的:package public class BasicClass public function doSomething():void trace(Im doing something); package public class SubClass extends BasicClass public function saySomething():void trace(Im saying something); 第一个类作为父类并只有一个方法.实例化BasicClass并直接调用其方法.var basicClass:BasicClass = new BasicClass();basicClass.doSomething();没什么特别的.由SubClass的定义我们可看到它继承了BasicClass.这样它便可以用BbsicClass的属性或方法.现在看看:var subClass:SubClass = new SubClass();subClass.doSomething();subClass.saySomething();subClass调用了从BasicClass继承的doSomething()方法.不但可以从自定义的类继承,也可以继承一些内置的类.现在看一下创建Sprite的子类:package import flash.display.Sprite; public class extendedSprite extends Sprite 注意需要在包声明下面加入这句:import flash.display.Sprite; 为了继承在当前包中没有的类,你需要声明一个引入.引入相关的包和类.本例中的Sprite类从包flash.display引入.继承是创建新类的一种途径,以已有的类为基础-不是吗?这将使你的代码更清晰和精炼.但如果你想改变一个父类中已存在的方法? 如果你想完全的摆脱现存类的代码,直接改父类有时不可能,同时也不是一个好方法.当你用了一个第三方的类库如Papervision3D,很难想象你会修改它.当你直接修改了一些类后,一旦更新类库的版本后你的代码就失效了.幸运的是面向对象程序设计提供了一个解决方案.看一下我们如何在子类中修改BasicClass类的doSomething()方法.package public class SubClass extends BasicClass override public function doSomething():void trace(Hi, you need to do something ); public function saySomething():void trace(Im saying something); 我们为子类添加一个doSomething()方法.但必须明确说明此方法是覆盖了父类的同名方法.当覆盖后老方法便被替换了.在子类中依然可以调用被覆盖的父类方法.override public function doSomething():void trace(Hi, you need to do something ); super.doSomething();现在在SubClass中调用doSomething()方法,将输出:Hi, you need to do something Im doing something这里简单的解释了最基础的面向对象.借此你应该明白了一些基础面向对象,并能大概看懂面向对象的书,如果想了解的更多,在线的面向对象的书籍有一大堆.使用文档类和主应用文件文档类是在Flash IDE中才有,主应用文件在FlexBuilder或FlashBuilder中才有.文档类是只包含一个构造器的特殊类,当SWF文件载入时会调用它.也可以说文档类的构造器是你程序的入口.文档类必须是Sprite或MovieClip,或他们的子类.为了简单起见,本书只使用文档类不用主应用文件,虽然他们的名字不同,但作用却是一样. FlexBuilder和FlashBuilder获取并执行文档类的流程一样,但FlashIDE使用另一种方式.现在我们解释下FlashIDE的工作方式.设置Flash的文档类在Flash中,你可选择一个文档类作为你程序的入口.文档类可以是有时间轴的MovieClip的子类.将其放置到舞台作为应用的入口.虽然可以用舞台和文档类的组合来作为应用的入口,但不怎么常用.指定文档类非常简单.打开Flash,步骤如下:1. 新建as文件,保存为DocumentClassExample.2. 新建Flash(as3)文件保存为DocumentClassExample.Fla,与as文件同一目录.3. 打开FLA文件的属性面板.在最底下的右边有Document class的输入框.输入文档类的类名,本例是DocumentClassExample,下图: 到此就足够了.很简单是吧?在Flash中构造应用这些基本信息是非常重要的,不论是否是3d的应用.现在看一下发布后将发生什么.如果以上的步骤不对的话,Flash将抛出错误5007.5007: An ActionScript fle must have at least one externally visible defnition. 这是个可预知的错误.因为我们在属性面板定义文档类名却不存在相应的类.我们只创建了一个空的文件还没任何类的定义.当Flash无法继续工作就抛出刚才的那个错误.提醒我们出现了错误.现在我们修改此类.在Flash中打开DocumentClassExample.as,加入下面的代码并保存.package import flash.display.Sprite; public class DocumentClassExample extends Sprite public function DocumentClassExample() trace(Hello world!); 现在我们可以正常发布了.第三行我们看到此类继承了Sprite,这是必须的.构造器只输出了一行字符,发布后会在输出窗口看到这行字符.设置FlashBuilder,FlexBuilder的文档类 虽然这是可以的,但在本书中不使用FlexBuilder或FlashBuilder来创建Papervision3D的应用.但这2个工具都可以处理ActionScript工程. FlashBuilder或FlexBuilder中创建文档类步骤相同.使用这2个工具可以自动创建文档类.现在看一下如何创建文档类:1. 新建一个ActionScript项目.2. 将其命名为DocumentClassExample.3. 单击Next直到看到Main application file的输入框,默认此处的值为工程名.As,本例中为DocumentClassExample.as.下图是新建ActionScript项目向导的第2步.自动命名的文档类.4.单机Finish就设定好了文档类.如果有多个类,可以随时在Flex Navigator(FlexBuilder)或Package Explorer(Flash builder)中更新文档类.(步骤为:在xxx.as右键选Set as Default Application,文件的图标变为即可).5.现在完成此类并输入Hello World.因为FlexBuilder和FlashBuilder为了运行你的代码必须指定一个文档类,之外不须更多的步骤.Debug方式运行你的代码,将看到trace出的字符.Papervision3D里3D场景基础 在我们开始写Papervision3D的代码前,我们需要知道更多一些Papervision3D面的3D.接下来的这部分会让你更明白所写的那些代码.这些概念跟Papervision3D用到的类有直接关系.本章,将使用这些来完成第一个应用.我们所说的对象都是3D场景里活动的元素.让我们看一下这些对象:场景Scene Scene是在3d空间由3d对象组成的一个整体.就如flash里有3个轴的舞台(stage)-x,y,z.每个可视对象都可以添加到场景.如不添加到场景中就不会在出现在屏幕上.摄影机Camera可以想象成一个真实的相机,它在3d空间中不断的记录场景的活动.摄影机确定了查看场景的点.因为3d空间的相机不是可视对象,它不是场景的组成部分不必添加它.摄影机可以像真实的相机一样缩放和聚焦.3d空间的相机可以做更多的事.如,在3d中对象距离相机过近或过远时将剔除此对象防止它被渲染.相机可以忽略某些在不可见区域的对象.这些都是出于性能考虑的.对象距离太远或处于相机后面,不需来记录,这时会节省很多计算的资源.观察口Viewport观察口是一个舞台上的sprite容器,输出相机记录下来的对象.对象介绍中,观察口好比相机的镜头.镜头是我们放在3d场景上面的窗口.我们可以缩小这个窗口则可以只看到3d场景的一小部分,放大一些就看的多一些.观察口如现实中真实窗口一样窗口越大看到的外面世界越大,它影响到我们究竟可以看到多少场景.下面的图解包含了一个大的观察口,右侧是一个小而宽的观察口.黑边框画出了观察口区域.右侧的图很好的说明了观察口如何影响我们所看到的物体.3D对象在3d空间中的图形被称为一个3d对象,在Papervision3D中叫DisplayObject3D.可以将其想象成一个更高级的可视化对象如sprite和movieclip.不同的是 DisplayObject3D有第三个轴,我们可以让其绕3轴进行旋转.材质Material材质是附着在对象表面上的结构.当对象没有附着材质时,它是不可见的.可以使用很多材质.如一个简单的材质:颜色;高级的材质可能是:流(live stream).第四章会用到所有的材质.渲染引擎Render engine渲染引擎像一个滚动的相机.只要渲染引擎开始工作,它会输出相机记录下来的信息给观察口.当停止渲染引擎时观察口不会有任何新的信息输出仅仅会看到最后的那张图像.渲染是计算机中最繁重的任务,它需要重复计算你场景内部的对象并输出他们到观察口去.左手定则笛卡尔坐标系Flash,Papervision3D,都使用笛卡尔坐标系.在Flash中,一个规则的可视化对象可以通过设置x,y值改变其在舞台的位置.对象依靠x,y的值与舞台左上角的关系来确定位置.x值越大对象越靠右,y值增大对象便向下移动.Papervision3D里面的坐标系工作一致,只有2点不同之处.l Flash使用了笛卡尔坐标系的2个轴,而Papervision3D使用了3个轴l Papervision3D里的y轴与Flash里面的y轴相反.在Papervision3D中,我们不但要设置可视化对象的x,y轴,还要设置其额外的轴,为了确定对象的深度.第三轴称为z轴.在Flash中,依靠左上角的关系来摆放对象,这点是(0,0).称为中心点或原点.可想而知,Papervision3D中的原点是(0,0,0). 图中(+,-)的标志说明了坐标值相对于原点是增加还是减少.注意y轴与Flash2D坐标系是相反的.若准备将对象放置到屏幕的下方,需要给y轴更大的值.这是2D坐标的工作情况.上面的图解说明了Papervision3D坐标系里的y轴情况.(注:这样想Flash的坐标原点在屏幕的左上角,Papervision3D的坐标原点在屏幕的左下角)创建一个基础的Papervision3D类前面学习了基础场景的使用,和如何创建自定义类.现在我们要开始实践.使用你顺手的工具.第一个应用我们将创建一个3D场景包含一个可绕y轴旋转的球体.球体是Papervision3D内置的一个基本体.基本文档类首先,看一下定义了旋转球体应用结构的文档类.package import flash.display.Sprite; import org.papervision3d.cameras.Camera3D; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class FirstApplication extends Sprite private var scene:Scene3D; private var viewport:Viewport3D; private var camera:Camera3D; private var renderEngine:BasicRenderEngine; private var sphere:Sphere; public function FirstApplication() scene = new Scene3D(); camera = new Camera3D(); sphere = new Sphere(); scene.addChild(sphere); viewport = new Viewport3D(); addChild(viewport); renderEngine = new BasicRenderEngine(); renderEngine.renderScene(scene,camera,viewport); 现在细说下,我们可以在Flash,Flexbuilder,FlashBuilder中建立一个新工程之后创建一个名为FirstApplication的文档类.不要忘记在FlexBuilder,FlashBuilder中导入Papervision3D的代码.此前,我们了解到要把渲染结果输出到屏幕上我们需要一个 场景,摄像机,观察口,有材质的3d对象,和一个渲染引擎.注意文档类需要继承Sprite.之前我们需要将其引入.import flash.display.Sprite;import org.papervision3d.cameras.Camera3D;import org.papervision3d.objects.primitives.Sphere;import org.papervision3d.render.BasicRenderEngine;import org.papervision3d.scenes.Scene3D;import org.papervision3d.view.Viewport3D;现在,引入完毕,我们开始定义变量.private var scene:Scene3D;private var viewport:Viewport3D;private var camera:Camera3D;private var renderEngine:BasicRenderEngine;private var sphere:Sphere;我们只是定义了变量,并没有赋初始值.我们在构造器中进行赋初值.public function FirstApplication()现在开始创建一个3D场景.场景是必须的,是3D对象的载体.scene = new Scene();创建了一个无参的Scene3D类的实例.接着,添加一个Camera3D,跟创建场景一样容易.camera = new Camera3D();摄像机在创建时可以指定参数,现在使用默认值.只要场景中没有3D对象,场景和摄像机都很少用到.本例用到了一个内置的球体.sphere = new Sphere();Camera和Sphere都可以在创建时指定参数,若不指定则自动使用默认值.现在我们的球体创建完毕,需要加入到场景中,否则摄像机无法观察到它.如同在Flash中添加规则对象的步调一致,通过使用addChild().scene.addChild(sphere);看起来很像,对吗?现在我们拥有了一个场景,一个摄像机,和一个球体,现在我们需要建立好可以观察到3D场景的窗口.我们需要定义观察口并将其加入到舞台以使其可见.viewport = new Viewport3D();addChild(viewport);创建新观察口时,我们可以传递可选的参数,否则观察口将使用默认的参数.现在距离完工只有一步之遥了.我们需要获取到我们滚动的摄像机.这是渲染引擎定义好的,它将渲染场景并将拍到的图像发送至观察口.renderEngine = new BasicRenderEngine();renderEngine.renderScene(scene,camera,viewport);现在用渲染场景指令来渲染场景.运行后会得到一下的图像: 大小写敏感值得注意的是as代码大小写敏感.不仔细的话便会出错.以定义球体为例:var sphere:Sphere = new Sphere();这里我们看到我们定义了一个Sphere类型(大写),引用是sphere(小写),变量和属性的名字相同的话往往会导致错误的产生 这几行代码的结果可能看起来不是很美观,实际上这是令人振奋的开始,因为这在常规的Flash中是无法完成.当你编译完毕并显示出三角形时,你已经通过了本例中最困难的部分.让我们继续构建第一个应用并且看看我们如何给看起来还是很2d的对象添加3d效果.完成第一个应用 物体看起来很2d是因为目前还没有很明显的透视效果.同时场景还是静止的.当我们让球体绕某轴旋转时,我们将看到更好的效果.因为透视变化了,会让球体看起来更3d些.旋转前我们需要添加以下代码.在舞台上我们仅让渲染引擎执行了一次单独的渲染,然而,在真实的3D场景中是远远不够的.还记得我们说过我们需要一个摄影机吗?调用一次 renderScene 只会得到一次图形输出,就像照相机只拍了一张照片.这是不能实现滚动的效果的;我们需要每时每刻都进行渲染.最普通的做法是添加一个ENTER_FRAME事件监听用于时刻进行渲染.我们需要导入Event类,之后我们就可以监听ENTER_FRAME事件了.下面的导入语句加在类的上面import flash.events.Event;现在Event可用了,我们可以添加一个监听器.如下:renderEngine.renderScene(scene, camera, viewport);addEventListener(Event.ENTER_FRAME, render);每一次ENTER_FRAME事件,都会触发一次render方法.render方法内执行renderScene方法private function render(e:Event):void renderEngine.renderScene(scene, camera, viewport);每次播放头进入到新帧时,场景都会被渲染.但在目前的渲染只是一种浪费.场景没有改变时为什么需要进行渲染?因此,我们开始让球体绕y轴旋转.可以通过增加y轴的旋转值来完成,在render方法中加入.private function render(e:Event):void sphere.localRotationY +=1;renderEngine.renderScene(scene, camera, viewport);每一帧球体都会旋转一个角度.发布后查看此动画 这是球体旋转的截图!如果你使用的是Flashcs3,FlexBuilder,或FlashBuilder,你会发现动画不是很平滑.这是flash的帧率导致的.FlashCS3的默认是12fps,FlexBuilder默认是24fps,FlashCS4默认是30fps,帧率越高动画看起来越平滑.当然也会耗资源越多,帧率越高需要cpu计算量越大.这种情况下FlashPlayer将尽可能的绘制出更多的帧,结果造成动画的停顿. 目前还不会出现这种情况,往往出现在一个复杂的3d场景中.现在,我们需要改变一下默认的帧率.实际上没有最佳的帧率.本书中的帧率都用40.FlashIDE中可以设置下FLA的属性,Flex中只能通过代码改变了.可以给舞台加入帧率属性stage.frameRate = 40;通常这个值是文档类构造器的第一行代码.但可以放在任何地方.为了看到更平滑的动画,我们在文档类的构造器中加入.我们已经完成了第一个应用!发布后将看到一个绕y轴旋转的球体,现在运行的很平滑了.让我们重点看下这个类中的黑体部分.package import flash.display.Sprite; import flash.events.Event; import org.papervision3d.cameras.Camera3D; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class FirstApplication extends Sprite private var scene:Scene3D;private var viewport:Viewport3D;private var camera:Camera3D;private var renderEngine:BasicRenderEngine;private var sphere:Sphere;public function FirstApplication() stage.frameRate = 40; scene = new Scene3D(); camera = new Camera3D(); sphere= new Sphere(); scene.addChild(sphere); viewport = new Viewport3D(); this.addChild(viewport); renderEngine = new BasicRenderEngine(); renderEngine.renderScene(scene,camera,viewport); this.addEventListener(Event.ENTER_FRAME,render);private function render(e:Event):void sphere.localRotationY +=1; renderEngine.renderScene(scene,camera,viewport); 聪明的程序员使用更短的代码 例子FirstApplication是一个不错并且很小的Papervision3D类.每次我们准备创建一个Papervision3D应用我们可以拷贝这个类到新的应用中去.但有没有更简洁的方式呢?每个Papervision3D项目都包含了基本的组件摄影机、场景、渲染器、观察口.每次定义并引入这些类都在重复劳动.聪明的程序员便想办法找出一个更高效的方案.很幸运,Papervision3D包含了一个BasicView类.此类包含我们需要的基本组件.BasicView是继承自Sprite的,我们可以实例化它并加入到舞台去或用来扩展我们的文档类.本书将使用它.让我们来看一个绕y轴旋转球体的改良版本.package import flash.events.Event; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; public class BasicViewExample extends BasicView private var sphere:Sphere; public function BasicViewExample() stage.frameRate = 40; sphere = new Sphere(); scene.addChild(sphere); startRendering(); override protected function onRenderTick(e:Event=null):void sphere.localRotationX +=1; super.onRenderTick(); 构造器内部,我们需要设置一下工程的特殊值,如帧率和球体.在没有创建Scene3D对象,球体也可以添加到场景去.这些都在BasicView类中已经被创建好了.我们接着调用BasicView.startRendering()通知BasicView类开始渲染.一旦此方法被调用,会添加一个 ENTER_FRAME事件监听,事件发布后会一直渲染场景.我们只需在ENTER_FRAME事件监听中增加y轴旋转值即可.最简单的方式是 覆盖BasicView.onRenderTick(),重写后每次ENTER_FRAME时便会执行我们的代码了.我们必须调用super.onRenderTick(),以使父类正常工作.注意,BasicView里面的某些设置与FirstApplication的不一样,球体的尺寸会有变化.因为观察口在FirstApplication中是预先定义的,而在BasicView中则会随舞台的尺寸自动缩放 使用BasicView可以省下很多代码.当你比较继承自BasicView的类和FirstApplication类,你会发现代码行从43缩减到26,省下17行.本书中所有的例子都将使用BasicView类.为书中的例子做准备 现在我们知道如何创建一个继承自BasicView的文档类,更详细的说明放在了下一章.继承BasicView会节省很多代码书写时间,你不必再定义通用的属性和方法.本书的例子都继承自BasicView类.每次新开始一个项

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论