




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android初级培训教材1.2 基本的数据结构 (8课时 机上8课时)目录第一课时2教学目标什么是数据结构基本的数据结构及其优缺点关于数据结构的一些概念3第二课时4教学目标引言一维数组的创建一维数组的初始化一维数组数据项的访问6第三-四课时6教学目标61.2.3-4.1引言61.2.3-4.2多维数组声明71.2.3-4.3多维数组初始化71.2.3-4.4引用多维数组元素81.2.3-4.5锯齿数组9第五课时9教学目标枚举类型枚举类型的定义101.
2、2.5.3枚举的使用枚举具有的核心功能10第六-七课时12教学目标121.2.6-7.1引用型数据类型121.2.6-7.2引用类型的赋值131.2.6-7.3按值传递和还是按引用传递13第八课时18教学目标类对象成员变量成员方法211.2基本的数据结构(8课时)第一课时教学目标 数据结构的概念,基本的数据结构及其优缺点,和数据结构相关的几个定义(数据库,字段,关键字)。什么是数据结构数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排。数据结构包括数组,表,栈,二叉树,哈希表等。数据
3、结构可以解决哪些方面的问题呢?粗略的估计一下,可以用于以下三类情况:·现实世界数据存储·程序员的工具·建模现实世界数据存储现实世界数据值得是哪些描述处于计算机外部的物理实体的数据。看几个例子:一条人事档案记录描述了一位真实人的记录,一条存货记录描述了一个真实存在的汽车部件或杂货店里的一种商品,一条财务交易记录描述了一笔支付电费实际填写的支票。 举一个非计算机的现实世界数据存储的例子,有一叠3x5的索引卡片,这些卡片可以被用在不同的场合。如果每张卡片上写有某人的姓名,地址和电话号码,那么折叠卡片一定是一本地址簿。如果每一张卡片上写有家庭拥有物的名称,位置和价值,那么
4、这一定是一本家庭财产清单。 当然索引卡片并不能代表现在的科技发展水平。几乎索引以前用索引卡片处理的事务现在都可以用计算机来处理。如果想将旧式的所以卡片系统更新为计算机程序,边有可能会发现会被如下问题所困扰: ·如何在计算机内存中安放数据? ·所用方法适用于100张卡片吗?那1000张呢?10000000张呢? ·所用方法能够快速的插入新卡片和删除老卡片吗? ·它能快速的查找一张特定的卡片吗? ·若想将卡片按照字母顺序排列,又应该如何去排呢? 然而,大多数程序比所以卡片要复杂得多。想象一下机动车管理部门的数据库,这个库被用来记录驾驶员的执照的情况
5、;或者看一个航班预定系统,这个系统存储了旅客和航班的各种信息。这些系统由许多数据结构组成。 程序员的工具并不是所有的数据结构都用来存储现实世界的数据。通常情况下,现实世界的数据或多或少会由程序的用户直接存取。但是有些数据存储结构并不打算让用户接触,它们仅被程序本身所使用。程序员经常将诸如栈,队列和优先级队列等结构当作结构来简化另一些操作,这些数据结构就是程序员的工具了。 现实世界的建模有些数据结构能直接对现实世界的情况构造建模。其中最重要的数据结构是图。图可以用来表示城市之间的航线。电路中的连接线和连接点,或者是某一工程中的任务安排关系。其它诸如栈和队列等数据结构也会应用在时间的建模中。例如,
6、一个队列可以模拟顾客在银行中排队等待的模型,还可以模拟汽车在收费站前面等待缴费的模型等等。基本的数据结构及其优缺点知道了数据结构的概念及基本用途,那么到底有哪些数据结构,以及它们各自的优点和缺点有哪些呢接下来我们用下面的表格来对基本的数据结构以及其优缺点进行详细说明:数据结构优点缺点数组插入块,如果知道下标,可以非常快的存取查找慢,删除慢,大小固定有序数组比无序的数组查找快删除和插入慢,大小固定栈提供后进先出方式的存取存取其它项很慢队列提供先进先出方式的存取存取其它项很慢链表插入快,删除快查找慢二叉树查找,插入,删除都快(如果数保持平衡)删除的算法比较复杂红-黑树查找,插入,删除
7、都快,树总是平衡的算法复杂2-3-4树查找,插入,删除都快。书总是平衡的,类似的树对磁盘存储有用算法复杂哈希表如果关键字已知则存取极快,插入快删除慢,如果不知道关键字很慢,对存储空间使用不充分堆插入,删除快,对最大数据项的存储很快对其它数据项存取慢图对现实世界建模有些算法慢且复杂知道了这些基本的数据结构及其优缺点,那么我们再平平时的编程中选择正确的数据结构将会大大提高程序的运行效率。关于数据结构的一些概念数据库(database)我们将会使用数据库这个术语来表示在某一特定情况下所有要查阅的数据,数据库中的每一条数据都被认为是同样格式的,这种存储数据的统一格式就是我们前面所说的数据
8、结构。例如:如果使用索引卡片来做一本地址簿,其中所有的卡片便构成了一个数据库,没一张卡片就是一条数据,而卡片本身就是数据结构。 记录(record)记录是指数据库中划分成的单元。它们为存储信息提供了一个结构格式。在索引卡片的模拟系统中,每一张卡片就代表一条记录。当有许多类似的实体时,一条记录包含了某一个实体的所有信息。一条记录可能应对与人事档案中的某一个人,汽车供应存货目录中的某一个零部件,或是烹调书中的某一道菜谱。字段(field)一条记录经常被划分为几个字段。一个字段保存某一种特定的数据。在地址簿中的一张索引卡片上,一个人的名字,地址或电话号码都是一个独立的字段。更复杂的数据库程序使用带有
9、更多字段的记录。如下图显示了一条记录,其中每一行代表了一个不同的字段。雇员号码:社会保险号码:姓:名:地址:城市:省:邮编:电话:生日:开始工作时间:工资: 在java语言(和其它面向对象语言)中,记录经常被表示为一个相应类的对象。一个实例中各个变量表示不同的数据字段(data field)。 关键字在数据库中查找一条记录,需要指定记录的某一个字段位关键字(或查找关键字)。通过这个特定的关键字来进行查找。例如,在一个地址簿的程序中,可以再每条记录的姓名字段中查找关键字“Brown”。当找到具有该关键字的记录时,便可以访问它的所有字段,而不仅仅是关键字了,可以说是关键字释放了整个记录。还可以通过
10、电话号码字段或地址字段在整个文件中再次查找。上图中任何字段都可以被用作查找关键字。第二课时教学目标 一维数组的概念,一维数组的创建,一维数组的初始化,一维数组数据项的访问。引言 数组(array)是相同类型变量的集合,可以使用共同的名字引用它。它是应用最广泛的数据结构,被植入到大部分变成语言中。由于数组十分易懂,所以它被用来作为介绍数据结构的起步点,并展示面向对象变成和数据结构之间的关系。数组可以被定义为任何类型,可以是一维的也可以是多维的。数组中的一个特别要素是通过下标来访问他。数组提供了一种将有联系的信息分组的便利方法。下面我们来详细介绍一维数组。一维数组的创建
11、一维数组(one-dimensional array)实质上市相同类型变量列表。正如第一章所提到的,java中有两种数据类型:基本类型(如int,double等)和引用类型在许多编程语言中(甚至有些面向对象语言,如C+),数组也是基本类型,但在java中把它当作对象类型来对待,因此在创建数组时必须使用new操作符。要创建一个数组,你必须首先定义数组变量所需的类型。通用的一维数组的声明格式是:Type var-name; 获得一个数组需要两步。第一步,你必须定义变量所需的类型。第二步,你必须使用运算符new来为数组所要存储的数据分配内存,并把它们分配给数组变量。这样java中的数组被动态地分配。
12、如下所示: Int intArray; /声明一个数组变量 intArray = new int100 /给数组变量分配内存空间 或者使用等价的但语句声明方法: Int intArray = new int100; 操作符对于编译器来说是一个标志,它说明正在命名的是数组对象而不是普通的变量。当然还可以通过另一种语法来使用这个操作符,将它放在变量名的后面而不是类型的后面: Int intArray = new int100; 但是将放在int后面会清楚的说明是数据类型的一部分,而不是变量名的一部分。 由于数组是一个对象,所以它的名字(前面程序中的intArray)是数组的一个引用:它并不是数组本
13、身。数组存储在内存中的其它地址中,而intArray仅仅保存着这个地址。 数组有一个length字段,通过它可以得知当前数组大小(数据项的个数); Int arraylength = intArray.length; /取得数组长度 数组一旦被创建,其大小不可改变。一维数组的初始化当创建整型数组后,如果不另行指定,那么整型数组会自动初始化成空。与C+不同的是,即使通过方法(函数)来定义数组也是这样的。常见一个对象数组如下: autoData varArray = new autoData4000; 除非将特定的值赋给数组数据项,否则它们一直是特殊的null对象。如果尝试访问一个含
14、有null的数组数据项,程序会出项Null Pointer Assignment(空指针赋值)的运行错误。这主要是为了保证在读取某个数据项之前要先对其赋值。 使用下面的语法可以对一个基本类型的数组初始化,赋入非空值: int intArray = 0,3,6,9,12,15,18,21,24,27; 上面的语句可能简单的令人惊讶,它同时取代了引用声明和使用new来创建数组。在大括号中的数据被称为数据列表。数组大小由列表中数据项的个数决定。一维数组数据项的访问 数组数据项通过使用方括号中的下标数来访问。这与其它语言类似: Temp = intArray3; /定义一个有四个数据项的
15、数组 intArray7 = 66; /给第八个数组元素赋值为66 请注意无论是C,C+,还是java中,第一个数据项的下标都是0,所以,一个有10个数据项的数组小标是0至9. 如果访问小于0或者比数组大小大的数据项,程序会出现Array Index Out Of Bounds(数组小标越界)的运行错误。第三-四课时教学目标 多维数组概念,多维数组的声明,多维数组的初始化,多维数组长度的取得,锯齿数组的简单介绍。1.2.3-4.1引言 在学校里,由于一个班的人数不多,所以按照顺序编号即可,当人数增多时,例如对于学校里的人,在编号时就要增加层次,例如XX班XX号。在部队中也是这样,XX师XX团X
16、X营XX连XX排XX班,这里的层次就比较深了。为了管理数据的方便,一般要加深管理的层次,这就是多维数组的由来。 多维数组,指二维以及二维以上的数组。二维数组有两个层次,三维数组有三个层次,依次类推。每个层次对应一个下标。 在实际使用中,为了使结构清晰,一般对于复杂的数据都是用多维数组。关于多维数组的理解,最终的是理解数组的数组这个概念,因为数组本身就是一种复合数据类型,所以数组也可以作为数组元素存在。这样二维数组就可以理解成内部每个元素都是一维数组类型的一个一维数组。三维数组可以理解成一个一维数组,内部的每个元素都是二维数组。无论在逻辑上还是语法上都支持“数组的数组”这种理解方式。 通常情况下
17、,一般用二维数组的第一维代表行,第二维代表列,这种逻辑结构和现实中的结构一致。和一维数组类似,因为多维数组有多个下标,那么引用数组中的元素时,需要指定多个下标。下面以二维数组为例,来介绍多维数组的语法。1.2.3-4.2多维数组声明 多维数组的声明如下: 数据类型 数组名称; 数据类型 数组名称; 数据类型 数组名称; 以上三种语法在声明二维数组时的功能是等价的。同理,声明三维数组时需要三对中括号,中括号的位置可以在数据类型的后面,也可以在数组名称的后面,其它的依次类推。例如: int map; char c; 和一维数组一样,数组声明以后在内存中没有分配具体的存储空间,也没有设定数组的长度。
18、1.2.3-4.3多维数组初始化 和一维数组一样,多维数组的初始化也可以分为静态初始化(整体赋值)和动态初始化两种,其语法格式如下。 静态初始化以二维数组的静态初始化为例,来说明多维数组静态初始化的语法格式。示例代码如下: int m = 1,2,3, 2,3,4 ; 在二维数组静态初始化时,也必须和数组的声明写在一起。数值书写时,使用两个大括号嵌套实现,在最里层的大括号内部书写数字的值。数值和数值之间使用逗号分隔,内部的大括号之间也使用逗号分隔。 由该语法可以看出,内部的大括号其实就是一个一维数组的静态初始化,二维数组只是把多个一维数组的静态初始化组合起来。 同理,三维数组的静态初始化语法格
19、式如下: int b = 1,2,3, 1,2,3 , 3,4,1, 2,3,4 ; 说明:这里只是演示语法格式,数值本身没有意义。 动态初始化二维数组动态初始化的语法格式:数据类型 数组名称 = new 数据类型第一维的长度第二维的长度; 数据类型 数组名称; 数组名称 = new 数据类型第一维的长度第二维的长度; 示例代码:byte b = new byte23; int m; m = new int44; 和一维数组一样,动态初始化可以和数组的声明分开,动态初始化只指定数组的长度,数组中每个元素的初始化是数组声明时数据类型的默认值。例如上面初始化了长度为2X3的数组b,和4X4的数组m
20、。使用这种方法,初始化出的第二维的长度都是相同的,如果需要初始化第二维长度不一样的二维数组,则可以使用如下的格式:int n; n = new int2; /只初始化第一维的长度/分别初始化后续的元素n0 = new int4; n1 = new int3; 这里的语法就体现了数组的数组概念,在初始化第一维的长度时,其实就是把数组n看成了一个一维数组,初始化其长度为2,则数组n中包含的2个元素分别是n0和n1,而这两个元素分别是一个一维数组。后面使用一维数组动态初始化的语法分别初始化n0和n1。1.2.3-4.4引用多维数组元素对于二维数组来说,由于其有两个下标,所以引用数组元素值的格式为:数
21、组名称第一维下标第二维下标 该表达式的类型和声明数组时的数据类型相同。例如引用二维数组m中的元素时,使用m00引用数组中第一维下标是0,第二维下标也是0的元素。这里第一维下标的区间是0到第一维的长度减1,第二维下标的区间是0到第二维的长度减1。四、获得多维数组长度对于多维数组来说,也可以获得数组的长度。但是使用数组名.length获得的是数组第一维的长度。如果需要获得二维数组中总的元素个数,可以使用如下代码:int m = 1,2,3,1,1,3,3,4,2; int sum = 0; for(int i = 0; i < m.length; i+) /循环第一维下标sum += mi.
22、length; /第二维的长度相加 在该代码中,m.length代表m数组第一维的长度,内部的mi指每个一维数组元素,mi.length是mi数组的长度,把这些长度相加就是数组m中总的元素个数1.2.3-4.5锯齿数组 下面我们要介绍一种比较特殊的二维数组,可能大家也已经注意到了,在前面我们所举的例子中就有这么一种数组,它的第二维的长度是不一样的,我们把这种第二维长度不同的二维数组叫做锯齿数组。 锯齿数组直接初始化锯齿数据直接初始化的格式形如下面: int a = 1,2,3,4,5,6,7,8,9,0,1,2; 锯齿数组的动态初始化如下: int a ; a = new int4; a0 =
23、 new int2; a1 = new int6; a2 = new int1; a3 = new int3;第五课时教学目标 枚举类型的概念,枚举类型的使用,枚举类型的特点。枚举类型 我们已经知道,Java代码的两个基本的构造块是类和接口。现在又引入了枚举,一般简称它为 enum。那么什么是枚举呢,枚举其实就是一种类型,跟int, char 这种差不多,就是定义变量时限制输入的,你只能够赋enum里面规定的值。这个新类型允许您表示特定的数据点,这些数据点只接受分配时预先定义的值集合。 当然,熟练的程序员可以使用静态常量实现这项功能,就是我们常说的public sta
24、tic final代码。如下所示: Public class OldGrade public static final int A = 1; public static final int B = 2; public static final int C = 3; public static final int D = 4; public static final int F = 5; public static final int INCOMPLETE = 6; 但是在这样做的时候,请记住这类常量是 Java 中 int 类型的常量
25、,这意味着该方法可以接受任何 int 类型的值,即使它和OldGrade 中定的所有级别都不对应。因此,您需要检测上界和下界,在出现无效值的时候,可能还要包含一个 IllegalArgumentException。而且,如果后来又添加另外一个级别(例如OldGrade.WITHDREW_PASSING),那么必须改变所有代码中的上界,才能够接受现在的这个值。换句话说,在使用这类带有整型常量的类时,该解决方案也许可行,但并不是非常有效。幸运的是,枚举提供了更好的方法。枚举类型的定义 枚举类型在定义时要使用一个关键字enum,为 enum 提供了一个名称,并指定了允许的值。形如下面的
26、例子: Public enum GradeA,B,C,D,F,INCOMPLETE;枚举的使用 枚举类型最经常的用法,是使用枚举类型,在各个枚举值之间切换做各种分歧处理,及常用的switch语句。把枚举的各个值,作为switch语句的各个case来进行所需要的处理。当然必须切记的是这时候的switch语句中一定要在处理完所有的case后在加上default处理块,以免枚举类型被程序员修改后,我们在不知情的情况下,对这种新的枚举值漏处理,而且还发现不了错误。枚举具有的核心功能类型安全:枚举的申明创建了一个新的类型。它不同于其他的已有类型,包括原始类型(整数,浮点数等等
27、)和当前作用域(Scope)内的其它的枚举类型。当你对函数的参数进行赋值操作的时候,整数类型和枚举类型是不能互换的(除非是你进行显式的类型转换),编译器将强制这一点。比如说,用下面申明的枚举定义这样一个函数:枚举定义:enum Day SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;函数定义:Public void fun(Day);如果你用整数作为参数来调用这个函数,那么,编译器肯定会报错。fun(4); /错误要调用这个函数,参数必须严格使用上面枚举中所列举出来的值。紧凑有效的枚举数值定义: 定义枚举的程序应该很
28、简单,虽然java中也有类似于public static final的“准枚举”的定义,但这种枚举似乎很不简洁。如果有大量的数据要定义,这一点就尤为重要,你也就会感受更深。虽然这一点不如其他另外3点重要,但我们总是希望申明能尽可能的简洁。 无缝的和程序其它部分的交互操作: 语言的运算符,如赋值,相等/大于/小于判断都应该支持枚举。枚举还应该支持数组下标以及switch/case语句中用来控制流程的操作。比如: for (Day d = SUNDAY; d <= SATURDAY; +d) switch(d) case MONDAY: .; break; case TUESDAY: .;
29、break; case WEDNESDAY: .; break; case THURSDAY: .; break; case FRIDAY: .; break; case SATURDAY: case SUNDAY: .; 要想让这段程序工作,那么枚举必须是整数常数,而不能是对象(objects)。Java中你可以用equals() 或是 compareTo() 函数来进行对象的比较操作,但是它们都不支持数组下标和switch语句。运行的高效率: 枚举的运行效率应该和原始类型的整数一样高。在运行时不应该由于使用了枚举而导致性能比使用整数有下降。第六-七课时教学目标 引用型数据类型的概念,值传递
30、,引用传递。1.2.6-7.1引用型数据类型 早些时候的编程语言和初级程序员将每个变量看作相互无关的实体。例如,如果一个程序需处理某个日期,则要声明三个单独的整数:int day, month, year;上述语句作了两件事,一是当程序需要日、月或年的有关信息时,它将操作一个整数; 二是为那些整数分配存储器。尽管这种作法很容易理解,但它存在两个重大缺陷。首先,如果程序需同时记录几个日期,则需要三个不同的声明。例如,要记录两个生日,你可能使用:int myBirthDay, myBirthMonth, myBirthYear;int yourBirthDay, yourBirthMonth, y
31、ourBirthYear;这种方法很快就会引起混乱,因为需要的名称很多。第二个缺陷是这种方法忽视了日、月和年之间的联系并把每个变量都作为一个独立的值,每个变量都是一个独立单元。为了解决这个问题,Java引入了引用类型,允许程序员自己定义类型。 引用类型(reference type)指向一个对象,不是原始值,指向对象的变量是引用变量。在 Java 里面除去基本数据类型的其它类型都是引用数据类型,自己定义的class类都是引用类型,可以像基本类型一样使用。在Java 程序运行时,会为引用类型分配一定量的存储空间并解释该存储空间的内容。示例如下:public class MyDate privat
32、e int day = 8;private int month = 8;private int year = 2008;public MyDate(int day, int month, int year)public void print()public class TestMyDate public static void main(String args) / 这个 today 变量就是一个引用类型的变量MyDate today = new MyDate(23, 7, 2008);1.2.6-7.2引用类型的赋值 在 Java 编程语言中,用类的一个类型声明的变量被指定为引用类型,这是因
33、为它正在引用一个非原始类型,这对赋值具有重要的意义。请看下列代码片段:int x = 7;int y = x;String s = "Hello"String t = s;四个变量被创建:两个原始类型 int 和两个引用类型String。x 的值是 7,而这个值被复制到y;x和y是两个独立的变量且其中任何一个的进一步的变化都不对另外一个构成影响。至于变量s和t,只有一个 String对象存在,它包含了文本“Hello”,s和t均引用这个单一的对象。将变量 t 重新定义为:String t=”World”; 则新的对象 World 被创建,而t引用这个对象。上述过程被描述如下
34、:1.2.6-7.3按值传递和还是按引用传递这个在 Java 里面是经常被提起的问题,也有一些争论,似乎最后还有一个所谓的结论:“在 Java 里面参数传递都是按值传递”。事实上,这很容易让人迷惑,下面先分别看看什么是按值传递,什么是按引用传递,只要能正确理解,至于称作按什么传递就不是个大问题了。 按值传递指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:1. public class TempTest 2. private void test1(int a) 3. / 做点事情4. a+;5. 6.7. public static void main(String args) 8.
35、TempTest t = new TempTest();9. int a = 3;10. t.test1(a);/ 这里传递的参数a就是按值传递。11. System.out.println("main方法中的a=" + a);12. 13. 按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。第9行的a和第2行的a是两个变量,当改变第2行a的值,第9行a的值是不变的,所以打印结果是3。 我们把第9行的a称之为实参,第2行的a称之为形参;对于基本数据类型,形参数据的改变,不影响实参的数据。 按引用传递指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用
36、的地址,也就是变量所对应的内存空间的地址。示例如下:1. public class TempTest 2. private void test1(A a) 3. a.age = 20;4. System.out.println("test1方法中的age="+a.age);5. 6. public static void main(String args) 7. TempTest t = new TempTest();8. A a = new A();9. a.age = 10;10. t.test1(a); / 这里传递的参数a就是按引用传递11. System.out.
37、println("main方法中的age="+a.age);12. 13. 14. class A 15. public int age = 0;16. 运行结果如下: test1方法中的age=20 main 方法中的 age=20按引用传递的重要特点:传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。 要想正确理解按引用传递的过程,就必须学会理解内存分配的过程,内存分配示意图可以辅助我们去理解这个过程。用上面的例子来进行分析:(1) 运行开始,运行第 8 行,创建了一个 A 的实例,内存分配示意图如下:(2) 运行第 9 行,是修改 A
38、实例里面的 age 的值,运行后内存分配示意图如下:(3)运行第10行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的 a 变量。请注意:这两个a 变量是完全不同的,不要被名称相同所蒙蔽,但它们指向了同一个A实例。内存分配示意图如下:(4)运行第 3 行,为 test1 方法中的变量 a 指向的 A 实例的 age 进行赋值,完成后形成新的内存示意图如下:此时 A 实例的 age 值的变化是由 test1 方法引起的。(5)运行第4行,根据此时的内存示意图,输出test1方法中的age=20(6)运行第 11 行,根据此时的内存示意图,输出 main 方法中的
39、age=20 理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢? 就是 test1 方法里面的修改不影响到 main 方法里面呢?方法是在 test1 方法里面新 new 一个实例就可以了。改变成下面的例子,其中第3行为新加的:1. public class TempTest 2. private void test1(A a) 3. a = new A();/ 新加的一行4. a.age = 20;5. System.out.println("test1方法中的age=" + a.age);6. 7. public static void mai
40、n(String args) 8. TempTest t = new TempTest();9. A a = new A();10. a.age = 10;11. t.test1(a);12. System.out.println("main方法中的age=" + a.age);13. 14. 15. class A 16. public int age = 0;17. 运行结果为: test1方法中的age=20 main 方法中的 age=10为什么这次的运行结果和前面的例子不一样呢,还是使用内存示意图来理解一下:(1) 运行开始,运行第 9 行,创建了一个 A 的实例
41、,内存分配示意图如下:(2) 运行第 10 行,是修改 A 实例里面的 age 的值,运行后内存分配示意图如下:(3)运行第 11 行,是把 main 方法中的变量 a 所引用的内存空间地址,按引用传递给test1方法中的 a 变量。请注意:这两个 a 变量是完全不同的,不要被名称相同所蒙蔽。 也就是说:是两个变量都指向同一个空间。(4)运行第 3 行,为 test1 方法中的变量 a 重新生成了新的 A 实例的,完成后形成的新的内存示意图如下:(5)运行第 4 行,为 test1 方法中的变量 a 指向的新的 A 实例的 age 进行赋值,完成后形成的新的内存示意图如下:注意:这个时候 te
42、st1 方法中的变量 a 的 age 被改变,而 main 方法中的是没有改变的。(6)运行第5行,根据此时的内存示意图,输出test1方法中的age=20(7)运行第 12 行,根据此时的内存示意图,输出 main 方法中的 age=10 最后有两点说明: “在 Java 里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。 在 Java 里面只有基本类型和直接使用双引号定义字符串(String str = "Java ")方式的 String 是按值传递,其它的都是按引用传递。第八课时教学目标 类和对
43、象。类在面向对象的语言中,类是个很重要的概念。面向对象的方法把所有的处理对象进行归类。具有相同性质的对象归为一类。例如学校里有很多学生,每个学生都是一个对象,而“学生”则是一个类,它包含了所有在学校学习的人。 在Java语言里,对象是一组描述对象的属性和操作方法的集合,其中属性表明对象的状态,方法表明对象的行为。类是对象的定义。一个对象具有哪些属性和方法,由类来决定。从编程角度看,类是一种复合数据类型,它封装了一组变量和方法(函数)。 声明一个类的一般形式如下所示:修饰符 class 类名 /类体 其中修饰符说明了类的属性,可以是public、abstract、final等。这些
44、修饰符的含意将会在后继的章节中介绍。类体就是类的成员变量和成员方法的声明。修饰符和类体的声明都是可以选的。下面是一个“人”的类的声明,虽然类体是空的: class Person 对象对象与类是不同但是又紧密相联的概念。类是对象的定义,对象由类来生成。类与对象的关系好比铸造车间里模具与产品的关系。模具只有一个,但是用这个模具可以浇铸出很多成型的产品出来,模具的形状决定了浇铸出来的产品的外形。在Java语言里用new关键字来生成对象,通常的格式为: 类名 对象名=new 类名(参数);这里的对象名可以是任意合法的Java标识符。new关键字后带小括号的类名称为构造方法(函数)。默认的
45、、也是最简单的构造方法是不带参数的,也可以自定义不同形式的构造方法以供不时之需。下例利用刚才的Person类来生成两个Person对象Mike和John:Person Mike=new Person(); Person John=new Person(); 用new Person()生成一个对象时不仅分配了内存空间还进行了一些初始化的工作,对象所包含的不仅只是各个属性名了,而是属性的具体值。如果没有给属性赋值,虚拟机会自动给它们赋于相应数据类型默认的初值。生成一个对象的过程也称为实例化,所以一个对象就是一个实例。Mike和John是对象名,对象名是用来引用对象的,对象里的变量和方法可以通过对象
46、名来引用,所以对象名也称为引用(Reference)。引用类似于C/C+中指针的概念,与指针不同,引用不是直接指向对象所在的内存位置,但是它包含了内存地址的信息。Java中并没有指针,以指针进行内存操作常造成不可预知的错误,还可能破坏安全性,也正是因为如此,Java被认为是“安全的”编程语言。在某些特殊的情况下,可能生成实例但不需要引用,那可以直接用new来实例化。如下所示:new Person(); new Person(); 上面两行程序生成两个Person对象,但是每次生成的对象分别占用不同的内存空间,改变其中一个对象的状态不会影响其它对象的状态。就像每次用模具倒出一个毛坯一样, 尽管两
47、个毛坯看起来很像,但它们绝对是两个不同的毛坯。成员变量在面向对象的思想中,通常用属性来描述对象的特征。在编程语言里,这一组从属于某类对象的属性是用变量来表示的,例如前文提到用来表示人的特征的身高、体重、姓名等等,就可以分别用不同类型的变量:double型的height、float型的weight、String型的name来表示。这些属于类的变量,称为类的成员变量。 声明成员变量的一般形式如下:修饰符 数据类型 成员变量名;其中修饰符说明了类的成员变量的属性,可以是public、protected、private、static、transient、final、volatile等等。
48、成员变量的类型可以是Java内置的或者是自定义的复杂数据类型,包括简单类型、类、接口、数组。例如,描述一个人有一座房产可以用House类型的变量house来表示,这里的House是用户自定义的类(复杂数据类型)。调用成员变量的一般形式是:实例名.成员变量名下面是一个“人”的类的声明,类名是Person。描述“人”的成员变量有:height、weight、sex、name、age等,还有房产house的声明。class Person double height; float weight; char sex; String name; int age; House house; class Ho
49、use public class E4_1 public static void main(String args) Person p_Bill=new Person(); p_Bill.age=26; p_Bill.height=180; p_Bill.weight=145; p_Bill.sex=m; p_B="Bill Gates" p_Bill.house=new House(); Person类有6个成员变量,其中5个是简单数据类型,1个是复合数据类型House。在类E4_1的main函数里生成了一个引用名为p_Bill的对象。通过这个p_Bill
50、这个引用可以访问到这个人的年龄、身高、体重等属性。 上例的程序可以在全部放在一个源文件中,源文件名为必须为E4_1。Java的一个源文件允许多个类的存在,但是文件名必须和public类一致,一个源文件中只也能有一个public类。 成员变量不需要显式初始化可以直接使用。其实,它们还是有被初始化过的,称为隐式的初始化。没有显式初始化的成员变量是在为对象分配存储空间时自动被初始化,各种类型的变量被赋于默认的初始化值,如下所示:byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char u0000(null) boolean false 所有复合
51、数据类型 null下例打印了隐式初始化的Person类成员变量。class Person double height; float weight; char sex; String name; int age; House house; class House public class E4_2 public static void main(String args) Person p_Bill=new Person(); System.out.println(p_Bill.age); System.out.println(p_Bill.height); System.out.println(
52、p_Bill.weight); System.out.println(p_Bill.sex); System.out.println(p_B); System.out.println(p_Bill.house); 成员方法对象的方法可以用来改变对象的属性,或者用来接收来自其它对象的信息以及向其它对象发送消息。从编程角度看,类是一组Java语句的集合。这里说的方法和面向过程语言C、Pascal等中的函数其实是一个概念。但是在像Java这样的纯面向对象的语言里,“函数”只能包含在类里面,而且是用来描述类的行为的,一般称为方法。 定义方法的一般形式如下所示: 修饰符 返
53、回类型 方法名(参数类型 参数名,)throws 异常列表 /方法体 方括号中为可选项。修饰符可以是public、protected、private、static、final、abstract、native、synchronized等。返回类型既可以是简单数据类型,也可以是复合数据类型(数组、类或接口)。如果方法没有返回值,也必须在返回类型处用void声明。或者可以说,这个方法返回void类型。例如:void setHeight(),但是,一旦方法声明某种返回类型,方法体中必须用return关键字返回和声明类型一致的数据。throws用来声明抛出异常,见第七章异常处理与断言。 调用对象方法的一般格式是: 引用名.方法名(参数列表); 下例是一个person类比较完整的定义: public class E4_3 public static void main(String args) Person p=new Person(); p.setAge(30); System.out.println(p.getAge(); class Person private double height; private float weight; private char sex; private String name; private int age; public void se
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 22454-2025企业建模与体系结构企业建模构件
- GB/T 45556-2025植物源产品中戊聚糖含量的测定气质联用法
- 行政权的偏离与纠正机制试题及答案
- 高考语文内容考察方式的多样性试题及答案
- 高校火灾救援应急预案(3篇)
- 社区防火灾工作应急预案(3篇)
- 行业标准化对市场竞争的影响试题及答案
- 电影院火灾突发应急预案(3篇)
- 出租车行业火灾应急预案(3篇)
- 泵站火灾事故应急预案(3篇)
- 2025-2030年中国无缝钢管行业市场深度调研及竞争格局与投资研究报告
- 山东省济南市2025届高三三模化学试卷(含答案)
- 2022年新高考全国I卷数学真题
- 初三志愿填报家长会课件
- 2025年北京市租赁合同模板
- 粮食收购合同协议书范本
- 大学物理实验安全注意事项题试题及答案
- 2024年甘肃省临潭县事业单位公开招聘医疗卫生岗笔试题带答案
- 《工作报告写法》课件
- 【高三下】湖北省部分高中协作体2024-2025学年高三4月统考语文试题含答案
- 枯木砍伐施工方案
评论
0/150
提交评论