Java程序设计——04面向对象的基本概念.ppt_第1页
Java程序设计——04面向对象的基本概念.ppt_第2页
Java程序设计——04面向对象的基本概念.ppt_第3页
Java程序设计——04面向对象的基本概念.ppt_第4页
Java程序设计——04面向对象的基本概念.ppt_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

计算机科学与技术学院 赵志崑 赵志崑 面向对象的方法 面向对象的程序设计 程序的基本构件是类和对象,不是过程或函数 面向对象的分析 类和对象是名词,过程是动词 面向对象的方法更接近人的思维方式 提高软件开发效率 面向对象的程序设计只是一个环节 分析、设计、编码、维护 赵志崑 Java的面向对象特性 初级特性:基本的概念,即类和对象。 中级特性:核心的机制,即封装、继承 和多态。 高级特性:由初级特性和中级特性引出 的一些问题,如构造函数的使用、覆盖 的规则、静态变量和函数等。 赵志崑 类和对象 面向对象技术最基本的概念是类和对象: 类是一个样板,以操作、表示和算法的形式完整地定义了一 组对象的行为。它通常也是面向对象语言中的模块化、封装 和数据抽象的基础。 对象是类的一个实例,是一个软件单元,它由一组结构化的 数据和在其上的一组操作构成。 变量 方法 对象 赵志崑 抽象数据类型 class Car int colorNumber; int doorNumber; int speed; void brake() void speedUp() ; void slowDown() Car myCar = new Car(); myCar.speedUp(); 计算机中 对象的原型 现实生活中的对象 类实际上为实际的物体在计算机中定义了一种抽象数 据类型。 抽象数据类型是仅由数据类型和可能在这个数据类型上进行 的操作定义的。 使用者只能通过操作方法来访问其属性,不用知道这个数据 类型内部各种操作是如何实现的。 赵志崑 变量、方法和消息 对象的三个基本要素: 变量:指对象的数据,用来保存对象的状态,又称为实例字段 。 方法:指对象的功能单元。 消息:软件对象通过相互间传递消息来相互作用和通信。 对象B 对象 A 消息一个消息由三部分组成: 1. 接受消息的对象 2. 要完成方法的名字 3. 方法需要的参数 如myCar.speedUP(); 赵志崑 面向对象的程序设计 所有东西都是对象。 程序是一大堆对象的组合;通过消息传递 ,各对象知道自己该做些什么。(分而制之) 每个对象都有自己的存储空间,可容纳其 他对象。(由小到大) 每个对象都有一种类型。(举一反三) 同一类所有对象都能接收相同的消息。 赵志崑 类 定义类采用下面的语句: class 类名 成员定义 说明: 类的成员包括变量和函数,而且可以有多个。 成员函数可以使用成员变量。成员函数也可以调用其它成员函数。 对于成员函数来说,成员变量类似于C+中的全局变量,但其作用 范围仅限于类内部。一个类就划定了一个范围,在此范围内有“全局 变量”和一些函数。 class Student long id; char gender; int classID; void changeClass(int c) classID = c; 赵志崑 类和源代码文件 一个源文件中可以写多个类。 和源文件名字相同的类叫作主类,只有 主类声明前面可以有public。 一个源文件中可以没有主类。 将源文件编译后,每个类都会生成一个 .class文件。 赵志崑 构造函数 构造函数是类的一个特殊的成员 函数,用于初始化对象。 函数名和类名相同 不需要说明返回值类型(不是void) 规则: 每个类至少有一个构造函数,一个 类可以有多个构造函数。 如果没有为类定义构造函数,系统 会自动为其定义一个缺省的构造函 数,不带参数。 一旦为类定义了构造函数,则系统 不会再为其定义缺省构造函数。 class Student long id; char gender; int classID; public Student() id = 0; gender = F; classID = 0; public Student(long aID, char aGender, int aClassID) id = aID; gender = aGender; classID = aClassID; 赵志崑 对象和引用 用类声明的变量不是对象,而是对象引用,简称引用。 Student xiaoZhang;/ 声明一个Student类型的引用 声明引用并不创建对象,一个引用占4个字节,相当于对象指针 创建对象须使用new运算符,格式是: new 类的构造函数; 例如: new Student();/ 创建一个Student对象,无参构造函数 new Student(1, M, 2);/ 有参数的构造函数 让引用指向对象 xiaoZhang = new Student(); 通过引用访问对象,访问对象成员使用“.”运算符 xiaoZhang.id = 200328013203194L; xiaoZhang.changeClass(1); 赵志崑 类、对象和引用的声明 声明一个类: class 类名 变量声明,方法声明 class Student long id;/学号 char gender;/性别 int classID;/班级号,注意不能用class作属性名 void changeClass(int c) /更改班级 classID = c; 声明一个对象引用:类名 引用名 Student xiaoZhang; 创建一个对象: new 类构造函数 xiaoZhang = new Student(); /如果缺少这一步编译器会报错 使用对象:引用名 . 变量名 / 方法名 xiaoZhang.id = 200328013203194; 赵志崑 存储器分配 Student xiaoZhang;/声明一个Student对象引用 xiaoZhang xiaoZhang = new Student();/创建一个对象 先执行 new Student()再执行 xiaoZhang = xiaoZhang xiaoZhang xiaoZhang.id = 200328013203194;/使用对象 xiaoZhang 00000000 0000000000000000 0000 00000000 000000000x01abcdef 0000000000000000 0000 00000000 0x01abcdef 200328013203194 0000 00000000 赵志崑 对象析构 Java不支持析构函数。因为Java能够自动收集垃圾,所以不需要人 工的内存回收。 自动收集垃圾:当对象没有用处后,Java会自动的释放其占用的 内存。 好处:可靠性提高、使内存管理与类接口设计分离,减少了跟踪内 存管理错误的时间。 代价:对性能的影响、暂停、配置复杂性和不确定的结束。 分代收集:1.2及以后的JDK使用了多种策略混合的垃圾收集方式 ,称为分代收集,其中根据对象的年龄将堆分为几个部分,不同 的代是用不同的收集算法收集的。 引用计数:每一个对象都有一个关联的引用计数 对该对象的活 跃引用的数量。如果对象的引用计数是零,那么它就是垃圾。 跟踪收集器:从根集开始沿着引用跟踪,直到检查了所有可到达的 对象。可以在程序注册表中、每一个线程堆栈中的(基于堆栈的) 局部变量中以及静态变量中找到根。 赵志崑 参数传递 Java语言在参数传递中只支持值传递方式 如果方法的参数是基本数据类型(8个),在方法内改变形参 的值不影响方法外的实参的值。 如果方法的参数是对象引用,在方法内通过形参改变对象的 内容,方法退出后实参指向的对象的内容也改变,因为形参 和实参指向的是同一个对象。 void inc(int n) n +; int x = 5; inc(x); / x = ? class Count int n; void inc(Count c) c.n +; Count x = new Count(); x.n = 5; inc(x); / x.n = ? 赵志崑 引用与对象的内存分配 Student xiaoMing = new Student(); Student xiaoFang = new Student(); xiaoMing.gender = M; xiaoFang.gender = F; 说明: 结果xiaoMing.gender为M,因为 引用xiaoMing和xiaoFang指向不 同的对象。 ( xiaoMing= = xiaoFang)的结果为 false。此时对象相等的判断应该 用equals方法。 0x01abcdef? M ? xiaoMing 0x01abcdf5xiaoFang ? F ? 两个引用指向不同的对象 Student xiaoMing = new Student(); Student xiaoFang = xiaoMing; xiaoMing.gender = M; xiaoFang.gender = F; 说明: 结果xiaoMing.gender为F,因为引 用xiaoMing和xiaoFang指向同一个 对象。 ( xiaoMing= = xiaoFang)的结果为 true。xiaoMing.equals(xiaoFang)结 果也为true。 两个引用指向同一个对象 0x01abcdef? F ? xiaoMing 0x01abcdefxiaoFang 赵志崑 原始数据类型的内存分配 int xiaoMing = 100; int xiaoFang = xiaoMing; xiaoFang = 200; 说明: 结果xiaoMing为100,因为原始数据类型不存在指向同一 个对象的问题。 ( xiaoMing= = xiaoFang)的结果为false。 100xiaoMing 200xiaoFang 赵志崑 参数传递的例子 方法的参数是引用时,形参是对象引用的复制品,通 过形参访问的和实参访问的是同一个对象。 方法的参数是基本数据类型时,形参是实参的一个复 制品。 class Student int javaScore; class JavaClass score(Student aStudent, int aScore) /aStudent为引用型 aStudent.javaScore = aScore; aScore = 100; Student s1 = new Student(); JavaClass c1 = new JavaClass(); int x = 90; c1.score(s1, x); / s1.javaScore值为100,x的值还是90。 赵志崑 变量和作用域 局部(local)变量:在一个方法内定义的变量, 也被称作自 动(automatic)、临时(temporary)或栈(stack)变 量。局部变量只在方法内部起作用。 当一个方法被执行时, 局部变量被创建;当一个方法被终止时, 局部变量被清除。 局部变量必须使用之前初始化, 否则编译时将出错。 方法(包括构造函数)的入口参数是局部变量。 实例变量:在方法外而类的内部定义的变量,在使用 new Xxxx ()调用构造一个对象时被创建。 类的实例变量有默认的初始值,可以不用显式初始化。 boolean falseChar u0000(null) float 0.0f double 0.0d byte (byte)0short (short)0int 0 long 0L 局部变量可以取消非局部变量的作用 方法内声明的局部变量与类变量或实例变量可以重名。 此时缺省为局部变量。 若要使用类变量或实例变量,应使用this关键字。 赵志崑 变量作用域举例 class Student long id; char gender; int classID; void changeClass(int classID) this.classID = classID; int y = 0; for (int x=0; x10; x+) y += x; for (int x=0; x100; x+) y += x; ; 实例变量 局部变量 赵志崑 类的管理 当程序中的类非常多时,特别是由多人合 作开发时,如何管理类? 需要解决类名冲突的问题。 有没有类似的问题? 赵志崑 包 定义:Java允许把多个类收集在一起成为一组,称为包, 用来管理类。 目的:便于组织类,使自己的类和他人提供的类分离,避 免命名冲突,还可以提高编译速度。 分级:包可以嵌套,从而分成层次。如java.util,类似于硬 盘上的目录组织。一可以使每个包中的类不至于过多,二 可以保证类名的唯一性。 Java库中的包:标准Java库被分成许多包,并且分层。所 有的包都在java和javax包层次中。 赵志崑 package声明包 关键字package将源文件中的所有 类添加到一个包中。 如果源文件中没有package语句, 那么此文件的所有类将被放到默认 的包中。默认的包没有包名。 类的完整名称:包层次+类名 school.Student 执行类的命令:java school.Student JDK1.2以后的版本拒绝加载用户定 义的以java.开始的类,以防止对 java类库的恶意改写。 / Student.java package school; public class Student class Course package语句必须放在源 文件的头部,在所有的 类定义代码之前。 包名称全部采用小写字 符 赵志崑 类的可见性 将类组织到包中,那么类就有可见性的问题。 类声明时可以使用public说明可见性;或者不使用可见性 说明,默认为friendly;不允许使用其他修饰符。 public可见的类对包外是可见的,可以被其他包中的类使用。 friendly可见的类是包内可见的,只能被本包中的类使用。 每个源文件中只有主类(与源文件同名的类)能够是public的 。 赵志崑 import引入包 使用包:一个类可以使用自己所在包中的所有类,也可以使用来自其 他包中的所有public类。使用其他包中的public类有两种方式: 类名前加上完整的包名,如: java.util.Date today = new java.util.Date(); 使用import关键字,import的作用是给出一个指向此包中的类的快捷方式 。 import可以引入某个特定的类 import java.util.Date; Date today = new Date(); import也可以引入包中的所有类 import java.util.*; Date today = new Date(); 注意: 只能用*来引入一个包中的所有类,并不能嵌套引入下层包。例如,不能 使用import java.*或者import java.*.*引入所有包。 只能引入类,不能引入对象。如不能用import System.out。 Java缺省自动引入java.lang包中所有类,相当于import java.lang.*; 赵志崑 同名类的问题 问题:两个不同包中含有同名类,如java.util包和java.sql包中都有 一个Date类。下面的程序会出现编译错误,因为编译器不知道使 用哪个Date类: import java.util.*; import java.sql.*; Date today;/编译错误 解决方法:用一条特定的import语句指明用哪个类。 import java.util.*; import java.sql.*; import java.util.Date; Date today;/编译错误 若两个Date类都要使用,则只能在每个类前面加上完整的包名。 java.util.Date today = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(); 赵志崑 类文件的管理 类(class)文件的存放位置要和类所在的包对应 将包层次对应到文件目录层次 例如:zzk.school.Student类应存放到zzkschool目录下 执行命令:从当前目录开始查找相应的子目录和文件 java zzk.school.Student命令,需要从当前目录能够找到 zzkschoolStudent.class文件,这是一种相对位置。 源代码文件的存放位置 如果类A中用到了另一个类B,那么编译A时,编译器需要访问B的 class文件;或者找到B的源文件也行,此时编译器会先编译B。 所以一般情况下,java源代码文件的存放位置也会和类的包层次对 应。 编译命令:编译zzkschoolStudent.java文件,需要在zzk的上层目 录执行命令javac zzkschoolStudent.java 赵志崑 虚拟机如何定位类 虚拟机需要某个类时,需要找到该类文件 (.class文件)以及该类用到的其他的类。 类被存储在文件系统的子目录中,路径必须与 所在包名相匹配。 例如:java hello.Hello 调用虚拟机 类所在的包 类名 package hello; public class Hello 调用Java虚拟机时 命令行所在的目录 类文件的位置 赵志崑 classpath环境变量 可以使用java命令的-classpath 选项设置类的查找路径 ,可以简写为-cp,多个路径之间用;隔开。如:java classpath .;hello Hello; Java虚拟机在加载类的时候以这样一种方式查找具体的 类文件:classpath包存储的目录具体的类文件。 如classpath中有一个c:javaclassdir条目, 需要加载的类是hello.Hello.class, 在加载这个类的时候,虚拟机会查找c:javaclassdirhello目录 ,如果Hello.class在这个目录中,虚拟机就可以找到。 如果这个类不在这个目录中,同时也不在任何一个其它 classpath中,那么虚拟机会抛出一个ClassNotFoundException。 也可以将多个类文件及其目录结构保存在一个jar文件 中。 赵志崑 虚拟机查找类的路径顺序 虚拟机寻找类文件所使用路径的顺序: 首先自动搜索jre/lib和jre/lib/ext目录下的rt.jar和其他的jar文件 。 然后依次搜索-classpath中说明的路径。 注:查找文件时使用以包名为相对路径的文件名。例如import hello.Hello对于当前目录来说就是查找 helloHello.class文件。 Classpath的顺序和类版本冲突 Java虚拟机在加载类的时候查找classpath是有顺序的,如果在 classpath中有多个条目都有同一个名称的类,那么在较前位置 的类会被加载,后面的会被忽略。 这种按照顺序的类加载可能会导致类的版本冲突。很多时候 如果不注意这一点,可能会导致奇怪的异常。 赵志崑 编译器如何定位类 编译器在采用与虚拟机同样的查找文件方式之外 ,还要多做一些事情: 确定对象所属的确切类。如果源代码中使用了一个对 象,而没有明确指出类所在的包,那么编译器要检查 所有import语句确定类所在的包。如果发现两个包中都 有同名的类,则报告编译错误。 检查源文件是否有更改。编译器找到类(.class)文件后, 还要找到源文件(.java),并比较两个文件的最后更新时 间。若源文件比类文件新,则要重新编译源文件生成 类文件。 赵志崑 编译器与虚拟机如何定位类 编译器查找路径与虚拟机查找路径的区别: 编译器总是查找当前目录。而虚拟机只有在类路径中 包含当前目录(.)的情况下才查找当前目录。 如果没有设置类路径,缺省的类路径中包含当前目录。这就是 说,使用javac会搜索当前目录下是否有需要的文件;但是java cp dir Hello则只搜索.dir目录下是否有Hello.class文件,而不 搜索当前目录。 编译器只从当前目录下的类开始编译。 如果Hello.java不放在当前目录而是放在classpath目录,那么 javac Hello.java将找不到文件。如果Hello.java在当前目录下, 而Hello类中用到的其他类放在classpath目录中,则编译可以通 过。相反,java命令则可以执行不在当前目录下的类。 赵志崑 设置CLASSPATH变量 Java和javac命令都有-classpath选项,但是如果每次使用都需要设 置类路径,会非常冗长麻烦。因此,Java提供了另外一种选择,设 置CLASSPATH环境变量。 Win95/98/ME下:编辑autoexec.bat文件,添加一行 SET CLASSPATH=c:

温馨提示

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

评论

0/150

提交评论