您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 76《面向对象技术与方法》类与对象
7-1LectureNotesonObject-OrientedProgramming&DesignDr.LIWenjunlnslwj@mail.sysu.edu.cn第七讲类与对象(II)•Java语言的对象模型•变量的生存期★★•JVM存储空间组织★•对象实例的初始化★★★•对象实例的收尾★★★•Java语言的垃圾收集★★7-3•每一个面向对象系统都刻划了一种对象模型例如,Java语言的对象模型与C++语言的对象模型有很大差别。又如,OMG的对象模型定义了CORBA对象的共同语义。•对象模型定义了系统中的对象如何表示以及如何交互即描述了所谓的对象语义。例如,经典对象模型(classicalobjectmodel):一个客户程序向一个对象发送一条消息。而其他对象模型可能采用广播消息或其他通信方式。7.1Java语言的对象模型7-4•C++语言复杂:有两种方式操纵对象(1)以标识符直接标识对象:Complexc1(5,2);c1.print();//标识符c1代表一个对象本身(2)通过指针以标识符间接标识对象:Complex*c2=newComplex(5,2);c2-print();//标识符c2代表一个对象的指针•Java语言简单:只有一种方式操纵对象所有对象标识均是对象引用:Complexc3=newComplex(5,2);c3.print();//标识符c3代表一个对象的引用术语经常混淆使用:对象=对象引用(由上下文区分,必要时称对象实例或对象本身)。所有对象都是引用语义接近7-5•JVM规范并未规定对象的内部表示方式从而不约束实现者的创造性。•Sun公司JVM的一种实现方式句柄(handle)对象实例对象引用heapheapunder-specover-specunder-specover-spec7-6•对象与引用具有相关性Java程序员只能通过引用来操纵一个对象。包括创建对象和请求对象服务,但不包括对象撤销(是自动的)。•对象与引用具有独立性允许一个引用不与任何对象相关联(空引用null)。一个引用在某一时刻最多只能指称一个对象;在不同时刻可能指称不同的对象。允许一个对象在没有任何引用指称它时存在(等待收集的垃圾)。也可能有多个不同的引用指称它。•BruceEckel的比喻(不太贴切!)对象⇒电视机引用⇒遥控器[对象]引用vs对象[实例]7-7•虽然,引用类似于指针JamesGosling:...Thereferencevalues(oftenjustreferences)arepointerstotheseobjects,andaspecialnullreference,whichreferstonoobject.从内部实现看确实有许多相似之处。其实,Java的引用更类似于C++比C多出的引用类型。•但是,引用没有指针的语义指针支持算术运算,允许前后随意移动。⇒从而导致指针的诸多不安全性。引用仅能通过赋值指称新的对象(或null)。⇒不妨将引用理解为更安全的指针。引用vs指针7-8•字符串对象仅创建一个引用:Stringname;intlength=name.length();//错误!尚未关联对象。即创建一个引用,也创建一个对象,并建立两者的关联:Stringname=Zhang3;或:Stringname=newString(Zhang3);例子:字符串对象好的程序设计风格好的程序设计风格不好的程序设计风格不好的程序设计风格7-9•字符串常量是一个对象引用!intlength=Zhang3和李四.length();•字符串对象本身是一个常量(Immutable)!包括字符串常量或字符串变量所指称的。⇒意味着字符串的任何操作都不会改变字符串对象本身的值。Stringname1=Zhang3;Stringname2=name1.toUpperCase();仅对象引用才有此用法仅对象引用才有此用法原字符串对象本身未变,返回用new新建的另一字符串对象本身的引用原字符串对象本身未变,返回用new新建的另一字符串对象本身的引用从效率考虑,如果字符串容经常变动,则宜以StringBuffer取代String。从效率考虑,如果字符串容经常变动,则宜以StringBuffer取代String。7-10publicclassAge{privatestaticvoidprintAge(){Integerage=newInteger(18);System.out.println(年龄:+age);}publicstaticvoidmain(String[]args){printAge();}}引用的生存期vs对象的生存期age随printAge()结束而消失后,new创建的Integer实例仍存在。这些内存垃圾由JVM自动收集。age随printAge()结束而消失后,new创建的Integer实例仍存在。这些内存垃圾由JVM自动收集。7-117.2变量的生存期生存期:变量占有存储空间的期间。[分配空间-释放空间]1.两个不同的概念:生存期vs作用域!2.变量并没有包括对象实例:variable∈{primitive,reference}3.术语:variable∈typeobject∈class7-12创建create撤销destroy收尾cleanup服务service初始化initialize变量的生存期概览程序中每一个变量在使用(作为右值)前都必须有一个值。程序中每一个变量在使用(作为右值)前都必须有一个值。软件设计的审美:时间有序、空间有序。软件设计的审美:时间有序、空间有序。只有对象实例才需要执行与初始化对称的收尾工作。只有对象实例才需要执行与初始化对称的收尾工作。7-13•基本数据类型的变量只能保存基本数据类型的值。•引用类型的变量(对象引用,简称引用)要么指称一个对象实例,要么是null。要么是用户自定义的类或接口类型,要么是系统预定义的数组类型。两种类型的变量7-14•静态生存期(全生存期)静态数据:基本类型或对象引用常量数据:只有基本类型和String类型。对象本身并没有全生存期,必须在运行时用new创建!生存期随程序开始(类载入)而始,随程序终止(类卸载)而止。•动态生存期(ActivationOnDemand)局部变量(基本类型或对象引用)、对象实例。在需要时才创建、在不需要时撤销。两大类生存期不必考虑创建与撤销问题,只需考虑初始化不必考虑创建与撤销问题,只需考虑初始化谁负责创建?在哪里创建?谁负责撤销?如何初始化?如何收尾?谁负责创建?在哪里创建?谁负责撤销?如何初始化?如何收尾?7-15•类变量(classvariable)类声明中以static声明的域+接口声明中无论有否static声明的域。当类或接口就绪(载入)时,创建∼并初始化为默认值。当类或接口卸载时,∼视作不复存在。•实例变量(instancevariable)类声明中无前缀static声明的域。当创建类(或其子类)的实例时,创建∼并初始化为默认值。当所属的对象不再被引用时,∼视作不复存在。∼生存期结束前,其所属的对象将执行收尾工作。•数组成分(arraycomponent)是一些无名变量,一个数组对象实例可能含有多个数组成分。当创建数组对象的实例时,创建∼并初始化为默认值。当数组不再被引用时,∼视作不复存在。七类变量的生存期effectivelyceasestoexisteffectivelyceasestoexisteffectivelyceasestoexisteffectivelyceasestoexist7-16•方法参数(methodparameter)传递给方法的参数。方法参数声明唯一可用的修饰是final。当方法每次被调用时,都会创建一个新的参数变量(副本)并由对应调用的实际参数初始化。当方法体执行结束时,∼视作不复存在。•构造方法参数(constructorparameter)Java语言并不将构造方法当作类的成员(故无法继承)。隐式调用:创建类实例时;显式调用:子类的构造方法中。•异常处理程序参数(exception-handlerparameter)当try语句的catch子句捕获一个异常时,创建∼并初始化为异常关联的实际对象。当catch子句的块执行完毕时,∼视作不复存在。7-17•局部变量(localvariable)由局部变量声明语句引入。局部变量声明唯一可用的修饰是final。不同于C++语言:Java程序中不存在静态的局部变量。当控制流进入块或for语句时,该块或for语句中直接声明的∼都会创建一个新的变量。直到执行局部变量声明语句时,才利用初始化表达式初始化∼。当块或for语句执行结束时,∼视作不复存在。局部变量没有默认的初始值!在大多数情况下,也可认为局部变量是在执行声明语句时创建的!7-18classPoint{staticintnum;//num是类变量intx,y;//x和y是实例变量int[]w=newint[10];//w[0]是一个数组成分intsetX(intanX){//anX是方法参数intoldX=this.x;//oldX是局部变量this.x=anX;returnoldX;}}7-19•类变量、实例变量、数组成分均有默认的初始值变量在创建时被自动初始化为默认值。•方法参数、构造方法参数、异常处理程序参数由相应调用的实际参数初始化•局部变量没有默认的初始值局部变量必须由程序员显式地设置初始值。既可以使用初始化表达式,也可以使用赋值表达式完成初始化。变量的初始值7-20•各种类型变量的默认初始值类型默认初始值byte(byte)0short(short)0int0long0Lfloat0.0fdouble0.0dchar'\u0000'booleanfalse引用类型null7-21classPoint{staticintnpoints;intx,y;Pointroot;}classTest{publicstaticvoidmain(String[]args){System.out.println(npoints=+Point.npoints);Pointp=newPoint();System.out.println(p.x=+p.x+,p.y=+p.y);System.out.println(p.root=+p.root);}}输出:npoints=0p.x=0,p.y=0p.root=null输出:npoints=0p.x=0,p.y=0p.root=null7-22•除无名的数组成分外,其他变量前均可修饰final包括类变量、实例变量、三类参数变量、局部变量等。•只能被赋值一次(否则导致编译错误)既可使用初始化表达式,也可使用赋值运算符。⇒注意:没有初始值的符号常量不可用作右值。既然可以被赋值,就可以用变量表达式设置符号常量的初始值。三种参数变量由参数传递机制自动赋值。•不同于C++语言C++符号常量只能初始化,禁止赋值;故必须使用初始化表达式。初始化表达式必须是一个编译时可求值的常量表达式。final变量(符号常量)7-23•空白符号常量(BlankFinal)指在声明中没有初始化表达式的符号常量。⇒通常在构造方法或初始化块中初始化它们。•对象引用的符号常量final只能保证对象引用始终指称同一对象实例。对象实例本身的状态仍可能由对象上的操作改变。⇒注意对数组而言也成立(数组成分被改变),因为数组也是对象。7-24classPoint{privateintx,y;privateintuseCount;publicfinalstaticPointorigin=newPoint(0,0);Point(intx,inty){this.x=x;this.y=y;}}但是,该对象实例的状态可能改变,
本文标题:76《面向对象技术与方法》类与对象
链接地址:https://www.777doc.com/doc-5324291 .html