1、Java 编程基础1.1. 基本概念 什么是软件软件是一系列按照特定顺序组织的计算机数据和指令的集合。程序设计的最终结果是软件。系统软件: 系统软件为计算机使用提供最基本的功能 . 例如: DOS, Windows, Linux, Unix, Mac OS, Android, iOS应用软件: 系统软件并不针对某一特定应用领域。而应用软件则相反,不同的应用软件根据用户和所服务的领域提供不同的功能。例如: Word, Excel, PPT, QQ, FeiQ, 凌波, UltraEdit, Eclipse 什么是计算机语言计算机语言指用于人与计算机之间通讯的语言。计算机语言是人与计算机之间传递信
2、息的媒介。为了使电子计算机进行各种工作,就需要有一套用于编写计算机程序的数字、字符和语法规划,由这些组成计算机指令就是计算机语言。软件就是由若干条计算机语言所组成的。 计算机语言分类机器语言: 机器语言是直接用二进制代码指令表达的计算机语言,指令是用 0 和 1 组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义。汇编语言: 汇编语言是使用一些特殊的符号来代替机器语言的二进制码,计算机不能直接识别,需要用一种软件将汇编语言翻译成机器语言。高级语言:使用普通自然语言进行编写源代码,通过编译器将源代码翻译成计算机直接识别的机器语言,之后再由计算机执行。 高级语言工作原理1.2
3、. Java 开发环境搭建 Java 平台分类JavaSE(Java Platform Standard Edition)Java 平台标准版,包含那些构成 Java 语言核心的类,可以理解为学习 Java 的基础JavaEE(Java Platform Enterprise Edition)Java 平台企业版,包含 JavaSE,并且还包含用 于 开 发 企 业 级 应 用 的 类准确的说 JavaEE 是一套用于企业开发的技术规范,包含很多组件,13 种核心技术,如:XML、JSP、Servlet、JDBC、Java Mail 等JavaME(Java Platform Micro Ed
4、ition) Java 平台微型版,包含 JavaSE 的一部分,另外提供一些用于小型设备上的类,例如:手机、机顶盒、汽车导航仪 下载地址http:/2009 年 SUN(Stanford University Network)公司被 Oracle 公司收购之后该地址跳转到Oracle 网站 JDK 与 JREJDK(Java Development Kit)Java 开发工具,包含开发 Java 程序的所有组件,包含 JREJRE(Java Runtime Environment)Java 运行环境,如果要运行 Java 程序,就需要 JRE 的支持常用组件:src.zip Java 是一门
5、开源的语言,其源代码都在这个压缩包中rt.jar Java 的基础核心类库,我们编写 Java 程序时使用的 class 都在这个 jar 包中javac.exe 编译器,将.java 源代码编译为.class 文件java.exe 虚拟机,运行 Java 程序的工具jar.exe 将 class 文件打成 jar 包的工具javadoc.exe 生成帮助文档的工具 常用 DOS 命令跳转到指定盘符: 盘符: 例:C: D: E: 跳转到指定目录: cd 目录 例:cd Itcastday01 cd TencentQQBin显示当前目录下文件: dir跳转到上级目录: cd跳转到根目录: cd
6、 清屏: cls 环境变量环境变量是指在操作系统中用来指定操作系统运行环境的一些参数path:如果想在任意目录下运行一个程序,我们就需要将程序所在的路径配置在 path 环境变量中。通常我们会将 javac.exe 所在目录配置到 path 中,因为我们需要在任意目录下都能编译Java 源文件。配置完成之后可以在命令行输入 javac 测试,如果显式帮助信息则是配置成功。classpath:Java 虚拟机运行时加载类的路径。JDK5 之后不配置默认为当前目录“.” 。如使用JDK1.4 或以下版本时需要人工配置。暂时不需要配置,默认加载当前目录下的所有 class 文件。配置方式:a 命令行
7、点击屏幕左下角开始 运行 输入 cmd 在命令行中直接输入命令进行修改查看变量值:set 变量名设置变量值:set 变量名= 变量值,多个值之间使用分号“;”分割,引用变量时使用“%变量名%”形式注意:此种方式仅适用于当前窗口b 我的电脑鼠标右键点击我的电脑 属性 高级 环境变量找到要修改的变量将其值修改,此种方式永久有效注意:配置环境变量之后可以查看编译器(javac.exe)和虚拟机(java.exe)版本,虚拟机版本不能低于编译器。使用哪个版本的编译器和虚拟机取决于 path 环境变量,如果虚拟机版本过低,可以通过环境变量来修改。编译器版本查看方式:javac version虚拟机版本查
8、看方式:java version JDK 版本JDK1.0、JDK1.1、JDK1.2、JDK1.3、JDK1.4、JDK5.0、JDK6.0 、JDK7.0JDK5.0 版本较 1.4 大幅变更,也从 1.4 升级为 5.01.3. 第一个 Java 程序 编写源代码新建文本文档,扩展名改为.java,在文件中写入代码。注意:windows 操作系统默认是隐藏已知文件扩展名的。请测试新建一个文本文档,如果看到的文件名是“新建 文本文档”而不是“新建 文本文档.txt” ,那么说明你的扩展名被隐藏了。请选择菜单栏中的 工具 文件夹选项 查看 下拉滚动条找到 “隐藏已知文件扩展名” 取消掉这一项
9、。 编译字节码文件a 左键单机屏幕左下角开始 运行 输入 cmd 启动命令行窗口b 使用 DOS 命令进入源代码所在目录c 使用编译器(javac.exe)编译源代码,javac 文件名.java ,编译后在该目录中会出现扩展名为 class 的字节码文件 运行程序使用虚拟机(java.exe)运行 class 文件,java 文件名,注意不要加扩展名,因为虚拟机只能运行 class 文件,扩展名省略不写,如写则报错。1.4. UltraEdit 使用使用记事本编辑 Java 程序有些麻烦,我们可以使用一些工具来帮助我们更好的编写 Java代码。UltraEdit 就是一款这样的工具,它提供了
10、显示行号、关键字高亮以及自动缩进的功能。注意:关键字高亮功能需要将当前操作文档保存成.java 文件之后才能使用。显示行号:视图 显示行号取消备份:高级 配置 备份 不要备份自动更正:高级 配置 语法高亮 取消自动更正关键字1.5. 进制 十进制由 0 到 9 的数字组成,逢十进一我们最常用的一种进制0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 二进制由 0 和 1 组成,逢二进一计算机中存储任何数据都是以二进制的形式进行存储的0 1 10 11 100 101 110 111 1000 八进制由 0 到 7 的数字组成,逢八进一八进
11、制在程序中以 0 开头0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 十六进制由 0 到 9 的数字和 A-F 的字母组成,逢十六进一十六进制在程序中以 0x 开头0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 进制转换a 十进制转二、八、十六进制除法取余,将要转换的数除以进制数,记住余数,再除以进制数,记住余数,直到这个数等于 0 为止,将所有余数反转就是对应的二进制表现形式。b二、八、十六进制转十进制乘法,将要转换的数编号,编号从低位开
12、始,从 0 开始,将每一位上的数乘以进制数的编号次方,最后将所有乘得的结果相加就是十进制表现形式。c二进制和八进制互转八进制的每一位对应二进制的三位。d 二进制和十六进制互转十六进制的每一位对应二进制的四位。 二进制负数一个负数的二进制表现形式就是这个负数忽略符号的正数对应的二进制取反再加一。计算机中存储的二进制数最高位是 0 则是正数,是 1 则是负数。1.6. 码表ASCII:英文码表,每个字符占 1 个字节。A 是 65,a 是 97GB2312:兼容 ASCII,包含中文,每个英文占 1 个字节(正数) ,中文占 2 个字节(2 个负数) 。 GBK、GB18030:兼容 GB2312
13、,包含更多中文,每个英文占 1 个字节(正数) ,中文占 2个字节(第一个负数、第二个可正可负) 。 Unicode:国际码表,每个字符占 2 个字节。Java 中存储字符类型就是使用的 Unicode 编码。UTF-8:国际码表,英文占 1 个字节,中文占 3 个字节。2. Java 语法2.1. 基本格式所有 Java 代码都应该在一个 class 中。 Java 是严格区分大小写的。 Java 是一种自由格式的语言。Java 代码分为结构定义语句和功能执行语句,结构定义语句以大括号结束,功能执行语句最后必须以分号结束。2.2. 注释单行注释和多行注释是在程序用来标记一些特殊的文本,这些文
14、本不参与编译运行。单行注释: / 注释内容多行注释: /* 注释内容 */文档注释是 Java 中特有的一种注释,它可以通过 JDK 中的工具(javadoc.exe)解析,生成帮助文档。文档注释: /* 注释内容 */2.3. 标识符 什么是标识符标识符可以理解为程序中我们自定义的一些名字,包括:包名、类名、函数名、变量名、常量名。 标识符的命名规则由大小写字母、数字、下划线(_)和美元符号($)组成,开头不能是数字。不能使用关键字。推荐使用全英文。 标识符通用规范类名、接口名:所有单词首字母大写,驼峰式命名,例如:XxxYyyZzz变量名、函数名:第一个单词首字母小写,其他单词首字母大写,
15、驼峰式命名,例如:xxxYyyZzz常量名:所有字母都大写,单词之间用下划线分割,例如:XXX_YYY_ZZZ包名:全部小写,例如:xxx.yyy.zzz2.4. 关键字abstract boolean break byte casecatch char class continue defaultdo double else extends finalfinally float for if implementsimport instanceof int interface longnative new package private protectedpublic return short
16、 static superswitch synchronized this throw throwstransient try void volatile while注:java 无 sizeof ,goto, const 关键字,但不能用 goto const 作为变量名2.5. 常量 整型整数,4 个字节。 长整型整数,8 个字节。以 L 结尾。 单精度浮点数小数,4 个字节。以 F 结尾。 双精度浮点数小数,8 个字节。 布尔只有两个值,真(true)或假(false) ,1 个字节。 字符单个字符,2 个字节。例如:a, 中, 5, u0026 , u0027在字符常量中,斜杠()是一
17、个特殊的字符,它的作用是用来转义后面一个字符,这些字符通常是不可见的或者有特殊意义的。r 回车,回到一行的开始n 换行,换到下一行t 制表符,键盘上的 Tabb 类似退格,键盘上的 Backspace以上字符都不可见,无法直接表示,所以用斜杠加上另外一个字符来表示。 单引号, Java 代码中单引号表示字符的开始和结束,如果直接写程序会认为前两个是一对,报错。“ 双引号, Java 代码中双引号表示字符串的开始和结尾,如果要写一个包含双引号的字符串那么这个双引号也需要转义。 斜杠, Java 代码中的斜杠是转义字符,用来和后面一个字符配合使用,在真正需要用斜杠的时候那么就要用另一个斜杠来转义。
18、以上字符都有特殊意义,无法直接表示,所以用斜杠加上另外一个字符来表示。 字符串由若干个字符组成的一串。可以是一个字符、多个字符、或者一个都没有。字符串没有固定大小。 空null,只有这一个值,用来表示一个引用为空。2.6. 变量int x = 5;System.out.println(x);x = 1 + 1;System.out.println(x);x = x + 1;System.out.println(x);上面的 x 就是一个变量,变量没有固定的值,是在内存中开辟的一片空间。Java 中的变量中只能存储同一种类型的值。变量在被取值之前必须初始化(第一次给变量赋值) 。 变量分类a基本
19、数据类型: 8 种整数:byte 1 个字节,最小值:-128,最大值:127short 2 个字节,最小值:-32768,最大值:32767int 4 个字节,最小值:-2147483648 ,最大值:2147483647long 8 个字节,最小值:- 9223372036854775808,最大值:9223372036854775807浮点数:float 4个字节,最小值:1.4E-45,最大值:3.4028235E38 double 8 个字节,最小值:4.9E-324,最大值:1.7976931348623157E308字符:char 2 个字节,最小值:0,最大值:65535布尔:
20、boolean 1 个字节,true 或 falseb引用数据类型:类、接口、数组都是引用数据类型,除了 8 种基本数据类型,其他所有类型都是引用数据类型。 类型转化a 自动类型转换在 byte、short、char 参与运算的时候会自动提升为 int,相当于将一个占空间较小的值放入了一个较大的空间。b 强制类型转换可以将一个占空间较大的值使用(类型) 的形式强制放入一个较小的空间,有可能损失精度。c 字符串转换任何值和字符串相加都会得到字符串。 变量的作用域与生命周期作用域:变量定义在哪一级大括号中,哪个大括号的范围就是这个变量的作用域。相同的作用域中不能定义两个同名变量。生命周期:变量的生
21、命周期从定义时开始,超出作用域后结束。变量生命周期以外不能使用。2.7. 函数(方法) 函数的定义函数就是一段有名字的代码,可以完成某一特定功能。如果有一段代码要使用多次,我们可以给它起个名字,每次使用时通过名字调用,这样就不用每次都写一大段代码了。如果某个函数在执行的时候需要调用者传入数据,那么可以定义参数列表,用于接收数据。如果函数运行之后需要返回给调用者数据,那么需要指定返回值类型,并且用关键字return 返回。定义函数的 3 个必要条件:返回值类型、函数名、参数列表。如果不需要参数也要写小括号,如果没有返回值类型要写 void。 名词解释形参:在定义函数时小括号中的参数,用来接收数据
22、的参数。实参:在调用函数时真正传入的参数,传递给函数的数据。参数类型:函数的参数的类型,一旦定义传入时必须匹配。返回值:函数运行结束后返回的值,使用 return 关键字返回。返回值类型:函数运行结束后返回的值的类型,在类型非 void 情况下必须返回,而且必须类型匹配。 函数的重载多个函数的函数名相同,参数列表不同(个数、顺序、类型) ,这就是函数的重载。在调用函数的时候通过传入的实参找到匹配的函数调用。函数的重载和返回值类型无关。2.8. 运算符 算数运算符加号:在操作数字、字符、字符串时是不同的,两个字符相加得到的是码表值,两个字符串相加是将字符串连接在一起。除号:整数在使用除号操作时,
23、得到的结果仍为整数(小数部分忽略) 。取模:模数(%右边的数)的符号忽略不计,结果的正负取决于被模数(%左边的数)。自增:符号在前就是先运算后取值,符号在后则是先取值后运算。习题:aSystem.out.println(3500 / 1000 * 1000);b某个培训中心要为新到的学员安排房间,假设共有 x 个学员,每个房间可以住 6 人,让你用一个公式来计算他们要住的房间数? 赋值运算符等于:可以多个连用,例如:x = y = z = 5;加等于:x += 5; 相当于 x = x + 5;面试题:以下代码正确的是? ( 多选) a. byte b = 1 + 1; b. byte b =
24、 1; b = b + 1; c. byte b = 1; b += 1; d. byte b = 1; b = +b; 比较运算符比较运算符会将运算符左右两边的值进行比较,运行结束之后返回的都是 boolean 值。注意运算符=不要写成= 逻辑运算符逻辑运算符操作的都是布尔值,运行结束之后返回的也是 boolean 值int y = 2;System.out.println(x+ = y System.out.println(x); System.out.println(y); int x = 1;int y = 2;System.out.println(x+ = y System.out.
25、println(x); System.out.println(y); int x = 1;int y = 2;System.out.println(x+ = y | +x y+);System.out.println(x); System.out.println(y); int x = 1;int y = 2;System.out.println(x+ = y | +x y+);System.out.println(x);System.out.println(y);System.out.println(false System.out.println(true | true int a = 2
26、;int b = a + 3 * a+;System.out.println(b);int a = 2;int b = a+ + 3 * a;System.out.println(b);int a = 1;int b = 2;System.out.println(a+b);尽量写简单的表达式,遇到运算符优先级的问题使用括号解决。2.9. 语句 顺序结构顾名思义,就是程序从上到下一行一行执行的结构,中间没有判断和跳转,直到程序结束。 选择结构程序具备多个分支,通过条件判断决定程序选择那一条分支执行a if 语句:通过 if.else if.else 决定程序流程。如果 if 中的条件满足则执行其
27、中语句,if 未满足则继续判断 else if,如果满足则执行,不满足继续判断下一个 else if,如果所有都不满足,则执行 else。练习:用 if else 语句判断一个数是奇数还是偶数。用户输入一个字符,用程序判断是否为小写字母,如果是,请输出“您输入的字符是小写字母”。 b switch 语句:通过 switch.case.default 语句控制程序流程。根据 switch 后括号中的值判断运行哪一个 case,这个值可以是byte、short、ch;ar、int。default 语句是可选的,如果所有 case 都不满足,则会执行 default。一旦匹配到一个 case,程序就
28、会从这个 case 向下执行,执行完一个 case 之后不会跳过其他的 case,如需跳过请使用 break。c 三元运算符语法:表达式 ? 结果 1 : 结果 2 如果表达式结尾为 true 取结果 1,为 false 则取结果 2。注意三元运算符也是有短路的效果,根据表达式的结果,只运行冒号一边的,另外一边的不参与运行。练习:定义一个函数,接收三个 int 参数,返回最大的一个。 循环结构通过循环条件控制同一段代码反复执行多次,执行完毕程序才会继续往后运行a while先判断 while 中的表达式结果是否为 true,true 则执行循环体,执行结束之后再次判断,如果表达式结果为 fal
29、se 则跳出循环。练习:打印出 0-9打印出 a-zb do.while先执行一次循环体,然后判断 while 中的表达式,如果是 true 继续执行,如果是 false则跳出循环。练习:编写一个程序,这个程序不断地读取键盘上输入的字符,直到读到字符q时,程序结束。c forfor 循环的括号中有三条语句,都是可选项。语句 1:这条语句会在整个循环开始之前执行,且仅运行一次,不参与循环。语句 2:必须是一个返回 boolean 值的表达式,如果写了这个语句那么每次循环开始之前会判断,true 则执行循环,false 则不执行。没写则直接执行。语句 3:这条语句在每次循环体运行结束之后执行。练习
30、:使用星号打印如下图案*i * 0 1* 1 2* 2 3* 3 4* 4 5i 空格 * 0 4 1 * 1 3 3* 2 2 5* 3 1 7* 4 0 9d continue、break、returncontinue:跳过一次循环,继续执行下一次break:结束循环return:结束方法2.10. 数组 什么是数组数组是一个类型一致,长度不可变的容器。可以通过索引操作容器中的每一个元素。如果有多个类型相同的数据需要存储,我们就可以将其定义为一个数组,这样做省去了创建多个变量的麻烦。 如何定义数组int arr = 1,2,3;定义 int 数组 arr,长度为 3,其中 3 个元素分别为
31、 1、2、3。这种方式只能在给数组类型变量赋值时使用。int arr = new int1,2,3;定义 int 数组 arr,长度为 3,其中 3 个元素分别为 1、2、3。可以在任何情况使用。int arr = new int3;定义 int 数组 arr,长度为 3。其中所有元素都为默认值 0。 访问数组元素、遍历数组存在数组中的数据是有索引的,从 0 开始递增,我们通过数组名和索引就可以操作其中每一个元素。例如:System.out.println(arr0); / 打印数组中索引为 0 的元素arr1 = 100; / 给数组中索引为 1 的元素赋值为 100数组的长度数组可以使用
32、length 属性获取其长度。遍历数组由于数组可以通过索引获取每一个元素,又可以通过 length 获取长度,那么我们就可以定义循环来遍历数组中的每一个元素了。 使用数组时的异常如果访问数组时索引越界(小于 0 或者大于 length-1) ,会抛出异常:ArrayIndexOutOfBoundsExcepion如果访问数组的引用为空(null),会抛出空指针异常:NullPointerException 数组练习a. 定义一个函数,将数组中所有元素打印。要求打印成一行,每个元素之间以逗号分隔。b. 定义一个函数,交换数组中的两个元素。c. 定义一个函数,找出数组中的最大数。d. 定义一个函数
33、,将数组中所有元素反转。例如:1, 2, 3 反转后为 3, 2, 1。e. 定义一个函数,对数组进行排序。f. 定义一个函数,对数组进行二分法查找。 与数组操作相关函数Arrays.toString() 查找帮助文档 Arrays 类,学习使用此方法将字符串转为字符串形式。将一个数组转为字符串表示形式System.arraycopy() 查找帮助文档 System 类,学习使用此方法拷贝数组中元素。将一个数组中的某些元素拷贝到另一个数组的指定位置 多维数组数组中的每一个元素都是数组,这样的数组就是多维数组。int arr = 1, 2, 3 , 4, 5 , 6, 7, 8, 9 ;定义二维
34、数组 arr, 其中有三个元素都是数组 , 第一个数组 3 个元素, 第二个 2 个元素, 第三个 4 个元素.int arr = new int 1, 2, 3 , 4, 5 , 6, 7, 8, 9 ;定义二维数组 arr, 其中有三个元素都是数组 , 第一个数组 3 个元素, 第二个 2 个元素, 第三个 4 个元素.int arr = new int33;定义二维数组 arr, 其中有三个元素都是数组, 每个小数组都是 3 个元素.int arr = new int3;定义二维数组 arr, 其中有三个元素都是数组, 每个小数组元素个数不确定.2.11. 综合练习a 编写一个程序,程序
35、接收键盘上输入的三个数,并输出这三个数的最大数。b 编写一个程序,它先将键盘上输入的一个字符串转换成十进制整数,然后打印出这个十进制整数对应的二进制形式。 c 使用移位方式将一个十进制数转换为十六进制。三种方式:0-9 之间的数值直接加上字符0 ,9 以上的数值减去 10 以后再加上字符A 定义一个数组,其中包含 0-F 这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。 Character.forDigit 静态方法可以将一个十六进制的数字转变成其对应的字符表示形式,例如,根据数值 15 返回字符F。 d. 编写一个程序,可以找出一个数组中的所有素数(质数) int
36、 arr = 1,2,3,4,5,6,7,8,9,10,11,12,13,143. 面向对象 3.1. 面向对象概念 什么是面向对象 面向对象(Object Oriented)是一种思想,90 年代以后软件开发的主流思想。 由于现实社会是由各种各样的事物所组成的,而我们编程又是在模拟现实社会,那么在程序也要用一些东西来表示现实社会中的事物,这些东西就是程序中的对象。我们在程序中使用这些对象,对其特征和行为进行操作进行编程,这就是面向对象编程。在使用面向对象编程思想之前,我们通常用面向过程的思想编程,先分析出解决问题的步骤,然后按照步骤一步一步实现。 面向对象编程的优点提高代码复用性。使用者无需
37、关心具体细节。 转变程序员角色,更加符合人的思维习惯。 3.2. 类与对象 什么是类类是用来描述对象的。由于对象是虚拟出来的东西,是看不见摸不着的,我们需要在程序中使用对象,就需要用一种方式来描述对象,然后根据这个描述来创建对象。 类和对象的关系对象是类的实例,类是对象的描述。 怎么定义类将一系列特征相似的对象的共同特征及行为抽取出来进行描述,写在一个 class 中,用成员变量描述对象的特征,用成员方法来描述对象的行为。class Person String name;int age;void speak()System.out.println(“My name is “ + name);S
38、ystem.out.println(“I am “ + age + “ years of age“); 怎么使用类创建对象使用 new 关键字和指定类名来创建一个对象。 对象的产生Person p = new Person();这句话先在堆内存中创建了一个对象,然后栈内存中创建一个变量引用了对象的地址。 成员变量初始化当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。基本数据类型初始化值为 0,引用数据类型初始化值为 null。 对象的使用当我们创建对象之后可以使用点语法来访问对象的属性和方法。例如:Person p = new Person();p.name = “张三“;
39、/ 访问属性(成员变量)p.age = 20;p.speak(); / 访问方法 对象的生命周期对象的生命周期从 new 关键字创建时开始,到没有任何引用到达对象时结束 (成为垃圾)。 匿名对象我们可以不定义变量引用对象,使用 new 关键字创建对象后直接使用,这样的对象没有名字,所以叫匿名对象。通常我们需要使用一个对象且只使用一次的时候,就可以使用匿名对象。比如将对象作为一个参数传递给另外一个函数。匿名对象因为没有任何引用到达,在使用一次之后即成为垃圾。3.3. 封装(Encapsulation) 什么是封装将一类事物的特征和行为定义在一起,可以通过这个定义创建对象,使用对象进行编程 封装时
40、需要将对象的属性和一些实现细节隐藏,仅对外提供必须的访问方式。 怎么封装将所有属性隐藏,提供公有方法对其访问。将不需要对外提供的方法隐藏。 封装的优点提高安全性:在访问对象的属性时候通过方法实现,在方法中可以进行校验。隐藏不必要提供的方法避免错误的调用。简化编程:使用者无需关心对象内部具体实现细节,只要根据对象功能调用指定方法。3.4. 构造函数(Constructor) 什么是构造函数构造函数是一个特殊的函数。函数名和类名相同。没有返回值类型。注意:没有返回值类型不等同于 void。在使用 new 关键字创建对象之后自动调用。 构造函数的重载构造函数的重载和普通函数相同,函数名相同,参数列表
41、不同即可。 构造函数的调用构造函数在 new 关键字创建对象时调用。构造函数可以在该类其他构造函数的第一个语句使用 this 关键字调用。 所有类都有构造函数每一个类都有构造函数,即使我们没有显式定义构造函数,也会生成一个默认无参的构造函数,其中没有任何内容。注意:这个自动生成的构造函数只在未定义任何构造函数时生成,如果我们定义了一个有参的构造函数,那么就不会生成无参的了。 构造函数的访问权限在定义构造函数时,如无特殊需要,应使用 public 关键字修饰构造函数。在一些特定情况下,我们不想让别人创建该类对象,那么可以使用 private 修饰构造函数,例如单态设计模式。3.5. this 关
42、键字this 关键字除了在构造函数中调用其他构造函数以外,还可以当做一个引用使用。其用于方法中,哪个对象调用该方法,this 就引用哪个对象。例如:方法中局部变量和成员变量重名,我们想调用成员变量时就可以使用 this.变量名形式访问成员变量。在方法中要将调用该方法的对象作为参数传递给另一个方法时,可以将 this 作为实参传给该方法。在内部类中访问外部类的成员时,需要使用外部类名.this.成员名形式访问。3.6. 函数的参数传递基本数据类型的变量作为实参传入函数之后,在函数中将形参改变,调用处的实参不变。因为基本数据类型的值是直接存在变量中,传入函数之后函数中的形参也同样存了一个值,这两个
43、值是没有联系的,所以函数中将形参改变时修改的只是函数中的变量的值,和调用处的实参无关。引用数据类型的变量作为实参传入函数之后,在函数中将形参改变,调用处的实参改变。因为引用数据类型变量中存储的是地址,传入函数之后函数中的形参存储的也是同样一个地址,函数中将这个形参改变时改变的都是同一个地址上的对象,所以一边改变两边都变。3.7. static 关键字static 关键字用来修饰类的成员,被这个关键字修饰的成员都和类加载有关。JVM 运行时不会将所有类加载到内存,因为无法确定程序中要使用哪些。类在第一次使用时加载,只加载一次。 静态变量用 static 修饰的变量就是静态变量。静态变量在类加载后
44、就初始化。静态变量被类的所有实例所共享。静态变量可以使用 类名.变量名 形式访问。如果在定义一个类的时候,发现一个成员变量需要被所有实例所共享,那么这个成员变量就需要定义为 static 的。 静态方法用 static 修饰的方法就是静态方法。静态方法在类加载后就可以使用。静态方法可以使用 类名.方法名 形式访问。静态方法不能直接访问外部非静态成员。因为外部非静态成员必须在类创建对象之后才能使用,而静态方法可以在没创建对象时就使用。如果要在静态方法内部访问外部非静态成员,需要先创建该类对象,通过对象访问。静态方法中不能使用 this 关键字。因为 this 是个引用,哪个对象调用方法就引用哪个
45、对象。 而静态方法有可能不是被对象调用的,this 无从引用。如果一个方法不用访问非静态成员,那么就可以定义为静态的,这样使用者就不需要创建对象,直接用类名调用。静态方法通常是作为工具方法或者一个可以产生对象的方法被声明,目的是为了让调用者更方便的使用,不必创建对象。 静态代码块用 static 修饰的代码块就是静态代码块。静态代码块在类加载后执行。静态代码块和静态方法相同,不能使用外部非静态成员。静态代码块执行和静态变量的初始化顺序由代码从上到下顺序决定。如果我们有一段代码想在别人使用某个类的时候就运行, 而且只运行一次, 那么就可以写在静态代码块中. 静态内部类用 static 修饰的内部
46、类就是静态内部类。静态内部类在类加载后就可以创建对象,无需创建外部类对象。具体内容详见 3.16 内部类3.8. 垃圾回收对象在没有任何引用可以到达时,生命周期结束,成为垃圾。所有对象在被回收之前都会自动调用 finalize()方法。一个对象在成为垃圾之后不会被马上回收,JVM 会检测内存中的垃圾堆积到一定程度时才会回收,如果我们不想等到这个时候才回收,可以使用 System.gc()方法来通知虚拟机回收垃圾。调用该方法之后 JVM 会开启新线程做处理垃圾的工作,这需要一定时间。3.9. 单态设计模式(SingletonPattern) 什么是设计模式在编程过程中我们经常会遇到一些典型的问题
47、或需要完成某种特定需求,而这些问题和需求前人也曾经遇到过,他们经过大量理论总结和实践验证之后优选出的代码结构、编程风格、以及解决问题的思考方式,这就是设计模式(Design pattern) 。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免得我们自己再去思考和摸索。 单态(单例)设计模式单态设计模式(Singleton pattern)就是要保证在整个程序中某个类只能存在一个对象,这个类不能再创建第二个对象。 单态设计模式的写法私有化构造函数,阻止创建新对象。由于需要返回一个对象,那么我们就需要在类内部自己创建一个对象,并使用成员变量记住它。由于该类不能创建对象,所以这个成员变量不
48、能是普通的成员变量,需要静态,这样在类加载之后就可以创建一个唯一的对象了。我们不希望其他类修改这个成员变量,所以将其私有。提供一个公有的方法用来获取唯一的一个对象。这个方法由于需要在不创建对象的情况下使用,所以需要静态。3.10. 继承(Inherit) 什么是继承在程序中,可以使用 extends 关键字让一个类继承另外一个类。继承的类为子类(派生类),被继承的类为父类(超类, 基类)。子类会自动继承父类所有的方法和属性。 为什么要使用继承 当我们发现一个类的功能不行,方法不够用时,就可以派生子类,增加方法。当我们需要定义一个能实现某项特殊功能的类时,就可以使用继承。最终还是为了一个目的,提高代码的复用性。当我们定义一个类时,发现另一个类的功能这个类都需要,而这个类又要增加一些新功能时,就可以使用 extends 关键字继承那个类,这样那个被继承类的功能就都有了,不必重写编写代码。这时只要在新的类中编写新的功能即可,原有代码就被复用了。 继承的特点Java 只支持单继承,不支持多继承,但是可以多重继承因为如果一个类继承多个类,多个类中有相同的方法,子类调用该方法时就不知道该调用哪一个类中的方法了。 向上