购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第2章
Java的基本语法

每种编程语言都有一套自己的语法规则,大多数编程语言的基本语法都是相似的。例如,在Java中定义一个变量用的语法是“int age=10;”,即定义一个整数类型(即int)的变量,变量名称为age,它的值是10;在PL/SQL语句中定义一个相同的变量为“declare age int:=10;”,其中declare为声明变量的语法块,age是变量名,int是数据类型,“:= ”中的冒号是赋值语句。如果学会了一种语言的语法,就很容易掌握另一种语言的语法。

变量是保存数据的地方,一个变量应该拥有它的数据类型,即保存什么类型的数据。一个变量应该有一个名称,以便于引用或使用。一个变量应该用具体的值表示它当前表示的值。变量保存在内存中,当程序退出后,变量及变量所表示的值将会消失。如果希望保存变量的值,就必须使用(学习)持久化技术。

2.1 Java程序的基本格式

Java程序代码必须放在一个类中,初学者可以简单地把一个类理解为一个Java程序。类使用class关键字定义。在class前面可以有类的修饰符。类的定义格式如下:

在编写Java程序时,有以下几点需要注意。

(1)Java程序代码可分为结构定义语句和功能执行语句,其中,结构定义语句用于声明一个类或方法,功能执行语句用于实现具体的功能。每条功能执行语句的最后必须用英文分号“;”结束,例如下面的语句:

System.out.println("这是第一个Java程序!");

请注意,一条语句结束必须使用英文的分号“;”,如果写成中文的分号“;”,编译器会报告illegal character(非法字符)错误信息。

(2)Java是严格区分大小写的。在定义类时,不能将class写成Class,否则编译器会报错。程序中定义一个名为computer类的同时,还可以定义一个Computer类,computer和Computer是两个完全不同的符号,在使用时务必注意。

(3)在编写Java程序时,为便于阅读,保持界面美观,通常会使用一种良好的格式进行排版。但这不是强制的,在两个单词或符号之间插入空格、制表符、换行符等任意的空白字符,编译器同样可以识别。例如,下面这段代码的编排方式也是可以的,但不提倡:

虽然Java没有严格要求用什么样的格式编排程序代码,但是,出于可读性的考虑,程序代码应整齐美观、层次清晰。推荐的编排方式是一行只写一条语句,符号“{”与语句同行,符号“}”独占一行。示例代码如下:

(4)Java程序中一个连续的字符串不能分成两行书写。例如,下面这条语句在编译时会出错:

System.out.println(“这是第一个 Java程序!”);

如果字符串确实很长,需要分两行书写,则需将此字符串分成两个字符串,然后使用加号“+”将这两个字符串合并,在加号后面换行。例如,可以将上面的语句修改成如下形式:

System.out.println(“这是第一个”+ “Java程序!”);

(5)注释是在Java代码中起到说明作用的文字,可以帮助代码开发人员快速、准确地理解代码。Java注释只在Java源文件中有效,在编译程序时,编译器会自动忽略这些注释,不会将注释编译到字节码文件中。在Java中,有3种注释类型,如表2-1所示。

表2-1 Java中的3种注释

例如:

int a = 10; //定义一个整型变量

2.2 Java中的关键字

Java中有一些预先定义并赋予了特殊意义的单词,称为关键字,也叫保留字,如class等。Java中的关键字如表2-2所示。

表2-2 Java中的关键字

每个关键字都有特殊的作用。例如,关键字package用于声明包,关键字class用于声明类等。所有的关键字都是小写的,我们在自行命名标识符时不能使用关键字。

2.3 Java中的标识符

标识符即变量名。声明变量时,每一个变量必须拥有一个名称,而声明名称必须遵循变量声明的规则。在Java中,声明变量或标识符的规则如下:

(1)标识符由字母、数字、下画线“_”、美元符号“$”或者人民币符号“¥”组成,并且首字母不能是数字。

(2)不能把关键字和保留字作为标识符。

(3)标识符没有长度限制。

(4)标识符对大小写敏感。

建议声明变量的规则:

(1)都使用字符并区分大小写。

(2)使用驼峰式命名,并具有一定的含义。例如,声明一个人的名称,可以声明为“String personName = "Jack";”,其中personName中name的第一个字母大写,即驼峰式命名。同时,通过这个变量名就可以知道它表示某个人的名称。

2.4 Java中的常量

常量就是在程序中固定不变的值,是不能改变的数据。例如,数字1、字符x、浮点数3.2等都是常量。在Java中,常量包括整型常量、浮点数常量、字符和字符串常量、布尔常量等。

1.整型常量

整型常量是整数类型的数据,有二进制、八进制、十进制和十六进制4种表示形式,具体如下:

● 二进制:由数字0和1组成的数字序列。从JDK 7开始,允许使用字面值表示二进制数,前面要以0b或0B开头,目的是和十进制数区分,如0b01101100、0B10110101。

● 八进制:以0开头并且其后由0~7(包括0和7)的整数组成的数字序列,如0342。

● 十进制:由数字0~9(包括0和9)的整数组成的数字序列,如198。

● 十六进制:以0x或者0X开头并且其后由0~9、A~F(包括0~9、A~F,字母不区分大小写)组成的数字序列,如0x25AF。

需要注意的是,在程序中为了标明不同的进制,数据都有特定的标识。八进制必须以0开头,如0711、0123;十六进制必须以0x或0X开头,如0xaf3、0Xff;整数以十进制表示时,第一位不能是0,0本身除外。例如,十进制的127,用二进制表示为0b1111111或者0B1111111,用八进制表示为0177,用十六进制表示为0x7F或者0X7F。

2.浮点数常量

浮点数常量就是在数学中用到的小数。Java中的浮点数分为单精度浮点数(float)和双精度浮点数(double)两种类型。其中,单精度浮点数后面以F或f结尾,而双精度浮点数则以D或d结尾。当然,在使用浮点数时也可以在结尾处不加任何后缀,此时JVM默认浮点数为double类型。浮点数常量还可以通过指数形式表示。

浮点数常量具体示例如下:

2e3f 3.6d 0f 3.84d 5.022e+23f

3.字符常量

字符常量用于表示一个字符,一个字符常量要用一对英文半角格式的单引号(' ')引起来。字符常量可以是英文字母、数字、标点符号以及由转义序列表示的特殊字符。具体示例如下:

'a' '1' '8' 'ri' '\u0000'

上面的示例中,'\u0000'表示一个空白字符,即在单引号之间没有任何字符。之所以能这样表示,是因为Java采用的是Unicode字符集,Unicode字符以\u开头,空白字符在Unicode码表中对应的值为'\u0000'。

4.字符串常量

字符串常量用于表示一串连续的字符,一个字符串常量要用一对英文半角格式的双引号(" ")引起来,具体示例如下:

"HelloWorld" "123" "Welcome in xxx" ""

一个字符串可以包含一个字符或多个字符,也可以不包含任何字符,即长度为0。

5.布尔常量

布尔常量即布尔型的值,用于区分事物的真与假。布尔常量有true和false两个值。

6.null常量

null常量只有一个值null,表示对象的引用为空。

2.5 Java中的变量

2.5.1 变量声明的语法

每一个变量声明语句最后必须以英文分号“;”作为人为结束符。

变量声明的语法如表2-3所示。

表2-3 变量声明的语法形式

以下是声明变量的示例(注意:声明在方法中的变量为局部变量,局部变量必须赋值)。

【文件2.1】 HelloWorld5.java

编译并执行后的结果如下:

D:\java>java cn.oracle.HelloWorld3 name变量的值为:mrchi age的值为:35 money的值为:34.5

2.5.2 Java中的数据类型

每一个变量必须拥有特定的数据类型,以表示它能表达的数据。在Java中,数据类型有两大类,即引用类型和基本类型,如图2-1所示。

图2-1

以下示例演示声明不同变量的方式。

【文件2.2】 HelloWorld6.java

每一种数据类型都有它们的取值范围。每种数据类型占用的字节数、取值范围、默认值等如表2-4所示。

表2-4 数据类型及取值范围、默认值等

2.5.3 数据类型与默认值

每一种数据类型都有自己的默认值,但只有变量声明为成员变量时才会有默认值。局部变量没有默认值,必须在赋值以后才可以使用。成员变量是指定义在类里面的变量,而不是定义在方法或者代码块中的变量。下面给出一个成员变量的示例。

【文件2.3】 HelloWorld7.java

以下代码演示变量的默认值。基本类型变量的默认值遵循表2-4定义的规则,引用类型的默认值都是null。

【文件2.4】 HelloWorld8.java

2.5.4 成员变量与局部变量

正如前面提到的,成员变量是声明到类里面的变量,具有默认值;而局部变量是声明到方法或者代码块中的变量,没有默认值,所以必须赋值以后才可以使用。下面给出一个成员变量和局部变量的声明示例。

【文件2.5】 DemoMemberVariable.java

在上面的示例中,除第3行中的变量为成员变量之外,第4、5、7行声明的变量都是局部变量。

2.5.5 在main方法中访问成员变量

main方法拥有一个关键字static,表示静态。在静态方法中,可以直接访问一个静态成员变量,但是访问非静态的成员变量时必须先实例化当前类。在声明成员变量时,使用static修饰符修饰静态变量。用static修饰的成员变量在内存的静态区,只有一个实例。非静态的成员变量也称为实例成员变量,每实例化一份当前类对象,都将会创建一个新的成员变量的实例。

以下示例将演示如何访问一个静态的成员变量。

【文件2.6】 DemoMemberVariable1.java

以下示例将演示如何访问一个非静态的成员变量。

【文件2.7】 DemoMemberVariable2.java

2.6 Java运算符和表达式

运算符是Java基础语法重要的知识模块之一,Java中有不同类型的运算符,如+(加)、-(减)都属于算术运算符。在编程语言中,一般分为一元运算符、二元运算符和三元运算符。一元运算符指只有一个数参与的运算符号,如!(叹号)为取反运算符。二元运算符和三元运算符是指参与运算的操作数分别为两个和三个。运算符又可分为算术运算符、关系运算符、逻辑运算符、位运算符,可以分别实现不同的运算。

2.6.1 Java中的运算符列表

先让我们了解一下Java的所有运算符。Java的运算符分为4类:算术运算符、关系运算符、逻辑运算符、位运算符。

● 算术运算符:+(加)、-(减)、*(乘)、/(除)、%(取模)、++(自加)、--(自减)。

● 关系运算符:==(等于)、!=(不等于)、>(大于)、>=(大于或等于)、<(小于)、<=(小于或等于)。

● 逻辑运算符:&&(短路与)、||(短路或)、!(非)、^(异或)、&(与)、|(或)。

● 位运算符:&(与)、|(或)、~(按位取反)、>>(右位移)、<<(左位移)、>>>(无符号位移)。

1.算术运算符

+(加)运算符可以对数值类型进行操作,相加的结果至少为int类型或较大一方的数据类型。

以下是一些加运算的例子。

【文件2.8】 Operation.java

-(减)、*(乘)、/(除)的运算与上面的类似,不再赘述。需要说明的是/(除)运算,如果参与的都是int或long类型,则只会返回整数部分。只有float和double参与运算时,才会返回小数。

+(运算)不仅可以进行数值的运算,还可以进行字符串的串联操作,使用+对任意对象进行+操作时,将按优先级将这个对象转成String。相加的结果也同样为String类型。

【文件2.9】 Operation1.java

在上面的代码中,第4行相加的结果为100Mrchi。按照运算的优先级,先计算10+90的结果(100),再与Mrchi进行字符串串联,结果为100Mrchi。

第5行的结果为Mrchi1090。因为先进行Mrchi与10的串联,成为字符串,再串联a2,结果为Mrchi1090。

采用%取余(取模)运算符,两数计算的结果为余数。

【文件2.10】 Operation2.java

++(自加运算符)分前缀++和后缀++。前缀++是指先加再用;后缀++是指先用当前的数,再进行自加操作。--(自减)同上。以下是示例。

【文件2.11】 Operation3.java

需要说明的是,++、--操作不会修改数据的类型。例如,以下两种代码所获取的结果不同:

2.关系运算符

关系运算符用于比较两个数值的大小,比较结果为boolean值。>=、<=、>、<可以直接比较两个数值,==和!=不仅可以比较数值,还可以比较任意对象的内存地址。

示例程序如下。

【文件2.12】 Operation4.java

第6行直接比较两个数值的结果为true。第7行,虽然c是对象类型,但是在JDK 1.5以后,会自动将c拆成int类型,所以也是直接比较两个值,结果为true。第8行为比较两个对象类型的内存是否一样,由于str2是一个新内存对象的声明,因此第8行的结果为false。

3.逻辑运算符

&(与)和|(或)既可以进行逻辑运算,也可以进行位运算。当&(与)两边运算表达式的值都为true时,结果为true;两边只要有一方为false,则结果为false。|(或)两边表达式的值只要有一个为true,则结果为true;只有两边都为false时,结果才为false。值得注意的是,&和|两边的表达式无论如何都会参与运算。

请见以下表达式:

两边都为运算表达式时,表达式两边都会参与运算:

&&(短路与)、||(短路或)的两边只能是boolean表达式。使用&&时,如果&&左边的表达式已经为false,则无论右边为true还是false,结果都是false,此时右边的表达式将不再参与运算,所以叫作短路与运算。同样的,对于||(短路或),如果左边已经是true,那么无论右边是true还是false都将为true,此时右边不再参与运算,所以叫短路或。

在进行比较时,虽然使用&&和||可以省去不必要的运算,但是也会带来一些问题,例如以下代码将不会抛出异常。

【文件2.13】 Operation5.java

在上面的第2行中,str为null值,如果直接调用str.length()获取长度,则会抛出一个NullPointerException异常,但是&&左边已经是false,右边不会参与运算,所以不会抛出异常。如果将&&修改为&,将会抛出NullPointerException异常,因为&两边都会参与运算,此时str的值为null:

使用^(异域运算符)时,两个表达式的值不一样时结果才是true,即:

!(非运算符号)为取反操作,如!true的结果为false,!false的结果为true。

4.位运算符

位运算符包含的符号有&(与)、|(或)、~(按位取反)、>>(右位移)、<<(左位移)、>>>(无符号位移),是对二进制数据进行运算,即运算的对象为0和1。

&(与)运算符的两边都为1时结果为1,示例如下:

【文件2.14】 Operation6.java

在上例中,c的结果为1,运算过程如图2-2所示。

进行|(或)运算时,只要表达式的两边有一个为1,结果就是1。

【文件2.15】 Operation7.java

在上例中,c的结果为15,运算过程如图2-3所示。

图2-2

图2-3

~是按位取反运算符号,若是1,则转换成0,若是0,则转换成1。

【文件2.16】 Operation8.java

在上例中,第4行的输出为-16。a的首位是0,按位取反以后为1,对于二进制来说,首位为1时为负数,所以b的值为负数。

在第6行中,通过Integer包装类型的静态方法将b转成二进制的结果为11111111111111111111111111110000,正是a值按位取反以后的结果。

>>(右位移)和<<(左位移)运算是将二进制数据向右或左进行位移,移出去的数据将在前面或者后面补0。

上面的向右位移运算过程如图2-4所示。

图2-4

向右位移两位以后,移出两个1,前面补两个0,所以最后的二进制结果为00000000_00000000_ 00000000_00000011,这个二进制数据的结果为3。

左位移运算同理,只是后面补0,不再赘述。

>>>为无符号位移运算符,对于>>右位移运算,如果为负数,则前面补1,即依然是负数。>>右位移运算的示例如下。

【文件2.17】 Operation9.java

在上面的代码中,a变量的二进制形式是以1开始的,所以为负数,使用>>右移两位,即后面去除两个0,则是有符号位移,所以前面补1,结果为-536870912,即11100000000000000000000000000000,依然为负数。如果使用>>>无符号位移,即将第2行的代码修改成“int b =a>>>2;”,结果为536870912,即00100000000000000000000000000000,也就是前面补0,结果为正数。对于无符号位移,无论是正数还是负数,前面都补0,有符号位移则会根据情况在前面补0或补1。

2.6.2 进制之间的转换

Java中的进制为二进制。二进制的声明以0b开始,后面带有0和1。八进制以0开始,最大数为7。十六进制的数以0x开始。

十进制的数字15,分别用二进制、八进制、十进制和十六进制表示,具体如下:

● int a1 = 0b1111。

● int a2 = 017。

● int a3 = 15。

● int a4 = 0xf。

将任意一个十进制数转成对应的进制,就是取余的过程,如将十进制数字38转成二进制,过程如图2-5所示。经过上面的运算结果,将余数从下向上串联,则十进制数字38的二进制为100110(前面的若干0省略)。其他进制的运算类似,这里不再赘述。

图2-5

值得说明的是,计算一个负数的二进制,先计算出它的正数的二进制反码,然后算补码,补码就是在最后添加1。例如,十进制数字38的二进制为100110,则-38的二进制为~38+1。计算过程如表2-5所示。

表2-5 一个负数的二进制计算过程

2.6.3 基本类型及其包装类型

每一个基本类型都有一个与之对应的包装类型,也叫作类类型。包装类型是工具类,表示对象。基本类型和包装类型的对应关系如表2-6所示。

表2-6 基本类型及其包装类型

下面以Integer为例讲解包装类型的功能。包装类型有很多静态方法,可以直接调用这些静态方法实现某些功能。

1.将字符串转成int或者Integer类型

【文件2.18】 Operation10.java

2.获取最大值或最小值
3.常用的进制转换

2.6.4 equals方法

equals用于比较两个对象里面的内容是否一致,==用于比较两个对象的内存地址是否一致。

【文件2.19】 Operation11.java

代码中的"Jack"为直接数。第1~2行直接赋值为Jack直接数,所以str1==str2或者str1.equals(str2)的结果都是true。str3使用new关键字重新分配了一个新的对象,所以str1==str3为比较内存地址,结果为false;但是两者的内容一样,所以str1.equals(str3)的结果为true。

建议在比较对象类型特别是String时使用equals方法,而不是使用==。

2.7 Java修饰符和包结构

面向对象的编程思想就是利用对象之间的相互作用完成系统功能,但对象间相互访问的过程中必然涉及访问安全问题,这是本章将要讨论的修饰符的范畴。package即包关键字,本质就是将类放到不同的目录或者文件夹下,以便于进行统一的管理。在Java中有很多包,它们不但对类进行统一的管理,还起到说明的作用,比如java.util.*包中的所有类都是工具类,java.net.*中的类都是与网络访问相关的类等。

在Java中有一个特殊的包java.lang,这个包中的所有类都会被默认导入所有Java类。例如,String、Integer、Double、System这些类都是在这个包下,这就是在我们之前开发的类中可以直接使用String等类的原因。

2.7.1 Java包结构

package关键字是包声明语句。一个类如果存在package关键字,则这个关键字必须在类的第一句,注释除外。包声明的语法以package开始,以;(分号)结束,比如“package cn.oracle;”,cn为第一层包,oracle为第二层包,即cn.oracle为完整的包名。在声明包名时,一般为公司倒置的网站名称。例如,某个公司的网站为http://www.abc.com,则这个公司声明包应该为“package com.abc;”。

如果一个类拥有包名,正像前面所讲到的那样,在使用javac编译时,应该添加-d参数,同时编译出包的目录结构。以下是一个带有包的类。

【文件2.20】 Hello.java

现在使用javac -d . Hello.java的方式来编译上面的源代码:

在编译好的目录下,可看到同时编译的以包命名的目录,如图2-6所示。

图2-6

现在使用java命令运行已经编译好的类,此时应该使用“java完整包名.类名”执行。

建议在声明类时至少应该有两层包。第一层表示国家或者组织,第二层表示公司名称。还可以加上第三层,表示模块或者功能。

在Eclipse中可以独立地创建一个包,如图2-7所示。

图2-7

也可以在创建类时直接指定包名,如图2-8所示。

图2-8

2.7.2 导入包

import关键字用于导入另一个类或者导入一个包下的所有类。import关键字必须声明在package关键字与class类声明之间,且可以多次使用import导入不同的类。

如果两个类在同一个包下,则不用import导入即可使用。

第一个类,代码如下。

【文件2.21】 Hello1.java

第二个类,代码如下。

【文件2.22】 World.java

在上例的代码中,由于Hello1类与World类在同一个包下,因此在World.java的第3行中可以直接使用Hello1类。

如果两个类在不同的包下,则必须使用import关键字导入才可以使用。

第一个类,代码如下。

【文件2.23】 Hello2.java

第二个类,代码如下。

【文件2.24】 World1.java

在上面的代码中,由于Hello2类与World1类不在同一个包下,因此当World1在使用Hello2类时必须导入。第2行就是导入Hello2类的语句。

可以使用*(星号)导入某个包下的所有类,但并不包含这个包下子包中的类。

第一个类,代码如下。

【文件2.25】 First.java

第二个类,代码如下。

【文件2.26】 Second.java

第三个类,代码如下。

【文件2.27】 Third.java

第四个类要使用First和Second类,可以使用*导入one包下的所有类,但并不包含one下子包a中的类。

【文件2.28】 Fourth.java

在上面的代码中,第2行直接导入了cn.one.*,即cn.one包下的所有类,所以可以在第4~5行直接使用First和Second类,但是Third类并没有导入,因此,如果第6行去掉注释语句,则会编译报错。建议使用哪一个类,就导入哪一个类。即将上面的代码修改如下。

【文件2.29】 Fourth2.java

第2~3行并没有使用*,而是指定导入的具体类。

在Java中有一个java.lang包,用于保存经常被使用的类。这个包也是被导入所有类中的。例如以下代码,由于已经默认导入了java.lang.*,因此没有必要再做import java.lang.*。

【文件2.30】 One.java

正是因为java.lang包是默认导入的,所以像String、Integer这样的类可以在项目中直接使用,这些类都在java.lang包下。以下是java.lang包下的部分类,读者可以通过查看API的方式获取这个包下的所有类,具体类的列表如图2-9所示。

图2-9

2.7.3 访问修饰符

权限修饰符号按权限范围从小到大分别为private、默认、protected和public。本节会涉及一些方法的调用,但不会太过复杂,所以不必担心。private声明的成员变量或者方法,只能当前类自己访问。public声明的成员变量或者方法,所有其他类都可以访问。这4个修饰符的功能如表2-7所示。

表2-7 4个修饰符的功能

包的功能如下:

(1)通过将相同名的类放到不同的包中加以区分。

(2)进行基本的权限控制。

(3)描述功能及模块。

需要注意的是,public和默认修饰符可以用于修饰顶层类(直接声明到文件中的类)。内部类(声明到其他类内部的类)可以被所有权限符号修饰。如下声明是错误的,因为使用private权限修饰符修饰了一个顶层类:

现在让我们通过代码来展示这些权限修饰符的可访问性。下面先从private开始。

1.private修饰符

private关键字表示私有的,可以修饰成员变量和成员方法,不能修饰局部变量。被private修饰的成员变量或成员方法只有当前类可以访问,其他类都不能访问另一个类的私有信息。以下代码访问的都是自己的私有成员信息。

【文件2.31】 PrivateDemo.java

在上面的代码中,第3行声明了一个实例成员变量,第4行声明了一个实例成员方法。这两个方法都不是静态的。在Java中,如果要从静态的方法中调用非静态的方法,就必须先实例化当前类,所以在第8行必须先声明PrivateDemo类的实例对象,即使用new关键字声明PrivateDemo类的实例。最重要的是,无论是public、protected、默认还是private,当前类都是可以调用的。

用private声明的成员方法或成员变量,其他类不能调用,如以下代码所示。

【文件2.32】 PrivteDemo1.java

【文件2.33】 InvokeDemo.java

在上面的代码中,第4行首先实例化了PrivateDemo类对象。然后在第5~6行访问私有的成员变量和成员方法。PrivateDemo中只有私有的成员变量和方法,第5~6行编译会出错,因为在InvokeDemo类中不能访问其他类的私有成员变量和成员方法。

2.默认修饰符

默认修饰符也可以叫作friendly(友好的),但是friendly并不是关键字。当一个方法或者成员变量没有使用任何权限修饰符时,默认的权限修饰符将会起作用。默认修饰符可以修饰类、成员方法和成员变量,表示同包中的类可以访问,同包中的子类也可以继承父类被默认修饰符修饰的成员或者方法。

下面展示在相同包下和在不同包下默认修饰符的访问能力。

第一个类,代码如下。

【文件2.34】 DefaultDemo.java

第二个类与DefaultDemo类在相同的包中,代码如下。

【文件2.35】 Demo01.java

在上面的代码中,由于class Demo01与DefaultDemo在相同的包中,因此在Demo01中可以访问DefaultDemo中的成员变量和成员方法,即第5~6行编译通过。

第三个类与DefaultDemo类在不同的包中,代码如下。

【文件2.36】 Demo02.java

在上面的代码中,由于Demo02与DefaultDemo不在同一个包中,因此第5~6行编译出错。因为在不同的包中不能访问另一个包的默认修饰符的成员信息。

第四个类与DefaultDemo类在相同的包下,通过继承访问DefaultDemo中的成员信息,并且继承将会在后面的章节中具体讲到。继承关键字为extends,通过extends可以让当前类变成另一个类的子类。

【文件2.37】 Demo03.java

在同一个包中,一个类可以通过extends关键字继承另一个类默认的、protected和public的成员方法和成员变量。所以,第8行和第9行的编译和运行都能通过。

3.protected修饰符

protected修饰符用于修饰成员方法和成员变量,主要用于描述被修饰的对象可以被同包中的类访问和子类继承。protected也用于描述继承关系,所以如果读者在Java API中发现一些方法被protected修饰,语义上这个方法主要用于让子类继承或者重写(后面会讲到重写的概念)。

以下代码展示在不同的包中,通过继承访问另一个类受保护的成员信息。

【文件2.38】 ProtectedDemo.java

以下声明一个不同包中的类,然后通过继承获取受保护的成员变量和成员方法的访问能力。

【文件2.39】 Demo04.java

上例的代码通过extends继承了ProtectedDemo。所以,在子类中可以直接访问父类中被保护的成员信息,即第4~5行的代码。

4.public修饰符

public修饰符表示公开、公有的。public修饰符可以修饰类、成员方法、成员变量,被public修饰的类叫公共类,可以被其他任意类声明。被public修饰的成员方法和成员变量,其他类都可以调用。

关于public的使用,在此不再赘述。

5.总结

权限修饰符用于修饰方法、成员是否可以被访问。值得说明的是,权限修饰符不能修饰局部变量。

用private修饰的方法或者成员变量只能被当前类访问。一般在企业的开发中不会直接暴露成员变量,所以成员变量一般都是用private修饰的。成员方法是为了让其他对象调用的,所以一般成员方法都用public修饰。

protected修饰符主要用于修饰成员变量和成员方法,语义上表示让子类继承。

public修饰符修饰的方法或成员是为了让所有其他对象访问。

在使用某一个修饰符时,要了解如何使用成员方法或者成员变量,然后添加不同的修饰符。

2.8 实训2:文件创建和数据类型转换

1.需求说明

在商超购物管理系统实现过程中,程序需要进行读取用户从键盘输入的信息、保存信息到文件、读取已存信息等数据处理工作。

2.训练要点

创建文件,数据转换类型后写入文件。

3.实现思路

(1)首先分别创建文件用来保存售货员名字cname、售货员密码password、商品名称gname、商品价格price、商品数量count和出售商品数量out。

(2)将其他类型的数据,如商品数量为int型,转换成字符型进行保存。

4.解决方案及关键代码

(1)使用File类创建一个对象,File类可以提供文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法。

(2)BufferedWriter将文本写入字符输出流,缓冲字符,以便高效写入单个字符、数组以及字符串。

(3)StringBuilder是一个可变的字符序列,当在一个循环中将许多字符串连接在一起时,使用StringBuilder类可以提升性能。

2.9 本章总结

本章主要学习了Java的基本语法,包括Java程序的基本格式、关键字、标识符、常量、变量,以及Java中的运算符和表达式,同时还学习了Java的修饰符和包结构。

2.10 课后练习

1.简要说明Java中的基本数据类型各占用几字节。

2.简述&和&&运算符的区别。

3.(  )是有效的标识符。

A.THIS

B.3name

C._3name

D.my Name(中间有空格)

4.int的取值范围为(  )。

A.-2 32 ~2 32 -1

B.-2 31 ~2 31 -1

C.-2G~2G-1字节

D.-128~127

5.(  )是正确的boolean值的赋值方式。

A.boolean boo = true;

B.boolean boo = null;

C.boolean boo= 0;

D.boolean boo = -1;

6.以下程序的输出结果为(  )。

int a = 9; int b = 10; String str ="Mrchi"; String str2 = a+b+str;

A.910Mrchi

B.19Mrchi

C.异常

D.没有结果

7.(  )表示八进制的8。

A.8

B.010

C.0x8

D.0b1000

8.优先使用(  )导入java.util.HashMap类。

A.import java.util.*;

B.import java.util.HashMap;

C.import java.*;

D.import HashMap;

9.对于以下两段代码,(  )是正确的。

A.类Two可以编译通过

B.类Two编译出错,因为第4行不能访问父类默认修饰的成员变量

C.类Two编译出错,因为第5行不能访问父类protected的成员变量

10.在Java代码中,被默认导入的包是(  )。

A.Java.util

B.java.net

C.java.lang

D.java.sql

11.(  )的结果为false。

String str1 = "Jack"; String str2 = "Jack"; String str3 = new String("Jack");

A.str1==str2

B.str1==str3

C.str1.equals(str3)

D.str2.equals(str3); fMzdvK+zicELkx0KnKmS8V5W/YyZax/INL6rgLquAB3Ew+GwbEzEJvHtqYZYPdGs

点击中间区域
呼出菜单
上一章
目录
下一章
×