版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第二章 开始学Java语法 任何一种程序语言,都有一些最基础的东西,这就是这门语言要处理什么样的数据,以及如何按着相应的规则组织和处理这些数据。千里之行,始于足下,本章将通过实例,用通俗的语言来讲述蕴涵在Java里的面向对象思想,通过学习我们可以发现:面向对象思想不是枯燥晦涩的教条,而是可以帮助我们更有效开发代码的指导工具。音乐家可以通过驾驭复杂的和声等技巧来创作优美动听的旋律,作家也从没有把把复杂浩瀚的语法条目当成他们创作的障碍,同样地,Java的语法细节也仅仅是开发项目的工具,希望大家在掌握初步的语法后,立即从面向对象思想和项目开发的需求的角度来观察语法定义的动机,学以致用,而不应该过多地
2、“从故纸堆中找学问”,刨根问底地研究“这个类有多少方法”等类的细节性的问题。2.1基本数据类型与操作符 基本数据类型的数据是构建Java程序大厦的砖瓦,我们在欣赏蕴涵Java大型项目里优秀架构和精密的内部实现细节时,不应该忽略Java语言里的基本类型数据。2.1.1基本数据类型 Java的基本数据类型分为4大类:整数、浮点数、字符型、布尔型。其中,整数包括byte、int、short、long,浮点数包括float、double。由于用不同位数(bit)来存放,它们所表示的精度和范围也有所不同,同时也有各自相应的默认值。如表2-1所示。表2-1 Java的基本数据类型关键字位数范围默认值byt
3、e8-2727-10short16-215215-10int32-231231-10long64-263263-10float323.4e-0383.4e+0380.0fdouble641.7e-3081.7e+3080.0dchar8u0000uffffu0000boolean8true或falsefalse整数型:byte、int、short、long。通常情况下整数型数据都是用十进制来表示,同样他们也可以表示成十六进制或八进制。十六进制以0x开头,如0x1F的十进制数值为31。八进制以0开头,如017的十进制数值为15。请大家注意,整数型变量在进行赋值时,要注意有可能会发生因为精度不够而
4、造成数据溢出的错误,例如:byte b;/ byte类型的数据最大为127,10000由于数据溢出而不通过编译b = 10000; 在Java语言里,浮点数型有float、double。浮点型数据用于表示小数。浮点型常量有两种表示方式:一般表示法和科学计数法。如一般表示法345.64的科学计数法为3.4564E2。默认情况下,浮点数常量为double,我们也可以在相应的数字后面添加相应的字母,f或F表示float类型浮点数,d或D表示double类型浮点数,如123.4f和123.4d前者用32位空间存储后者用64位存储。这里需要强调的一点是,在我们使用整数型数据和浮点型数据的过程中并不是用越
5、大的数据类型存放数据就越好,因为这样不仅有可能会造成一定的空间浪费而且还会提高相应得计算时间,因此我们应在确保不发生数据溢出的前提下选择合适类型来存放相应的数据。在Java语言里,字符型用char表示。它用来表示单个字符,它有两种赋值方式:单引号(而不是双引号)括起来的单个字符,用整数表示的unicode编码值。例如:char c1 = a;/表示97所对应的unicode编码achar c2 = 97;Java语言里,布尔型是boolean。用来表示真和假,它只有两个值true和false。2.1.2基本操作符操作符就是用来计算数据的符号,我们可以把数据通过操作符组合起来得到相应的结果。按着
6、操作符所操作数据的个数可以分为:一元、二元、三元,这一点比较好理解。按着操作符的功能可以分为:算术、赋值、关系、逻辑、位运算等操作符。接下来我们详细为大家介绍各种操作符的功能:算术操作符是用来描述整数和浮点数类型数据的运算规则的一组操作符。单目运算操作符包括“-”,“+”,“-”,它们都只能对一个操作数进行计算。“-”为求反符号,它表示计算操作数的相反数。“+”,“-”分别是自增和自减符号,它们会计算操作数的加一或减一的值,在使用这两个符号的时候需要大家注意操作符和操作数的位置对表达式结果的影响,例如:int i = 5;int j = 5;int k;/ i的值为6,表达式i+的值为6,k的
7、值为18k=i+*3;/ i的值为6,但表达式+i的值为5,k的值为15 k=+j*3; 注意:i+指表达式运算完后再给i加一,而+j指先给j加一然后再运算表达式的值。双目运算操作符包括“+”,“-”,“*”,“/”,“%”,它们可以对两个操作符进行计算,分别对应于加,减,乘,除,求余运算。需要注意的是前四种符号可以在整数和浮点数之间进行计算,而求余运算只能在整数之间运算。赋值操作符包括“=”和一些扩展的赋值操作符,如:“+=”,“-=”,“*=”,“/=”,“%=”。其中,”=”表示把等号右边表达式的值赋给等号的左边,而一些扩展的赋值操作符是一种简写形式,它们表示把左操作数按着相应的运算符号
8、的规则与右操作计算所得到的结果又符给了左操作数的那个变量,例如:int i = 5;/ 等同于a=a+6,故最终a的值为11a += 6; 关系操作符用于比较两个表达式的大小关系,计算的结果为布尔类型数据的true和false。如果表达式关系成立则结果为true,否则为false。关系操作符包括“= =”,“!=”,“”,“=”,“5为false,j5为false,表达式的值为falseb1 = ( i 5 ) & ( j 5); / 只要知道i5为false就可以确定表达式的值为falseb2 = ( i 5 ) & ( j 5);“&”与“|”要根据左右操作数的最终结果计算表达式的值,而“
9、&”与“|”如果可以根据左操作数的值能确定表达式结果就不会继续计算右操作数的值。位运算操作符是以二进制的方式操作数据,并且操作数和结果都是整数类型的数据,包括“”,“&”,“|”,“”,“”,“”,分别表示位反,位与,位或,位异或,带符号位右移,左移,无符号位右移。位反,位与,位或,位异或表示把左右操作数按着其二进制的表达形式对每个位的1或0进行相应的逻辑操作,再把新得到二进制数据转化成十进制数从而得到表达式的最终结果。后三种操作符表示把左操作数转化成二进制数据,然后按着右操作数的大小进行相应方向的移动,再把新得到二进制数据转化成十进制数从而得到表达式的最终结果,但需要注意的是同样是向右移动“
10、”表示带着符号位即最高位的1或0向右移动,而“”表示无论符号位是1还是0,都用0对最高位补位,如表2-2所示。表2-2 位移运算i二进制补码i2i270-17其它的重要操作符有:1. 条件操作符“(?:)”,它是唯一的一个三元操作符。使用方式如:i ? j : k ,其中i表达式的结果为布尔类型,如果i为true表达式结果为j,否则为k。2. 括号操作符“( )”,用于优先表达式的计算顺序。2.1.3操作符优先级 操作符的优先级决定了处理表达式计算的先后顺序,还有一个重要的特性就是结合性,它们共同决定了表达式按着何种方式来进行各种计算最终得到相应的结果,对于初学者来说建议使用括号来明确指定运算
11、顺序。各种操作符的优先级和结合性如表2-3所示。表2-3 操作符的优先级和结合性操作符优先级结合性,()1.2右,!,+,-3右*,/,%4左+,-5左,6左,=7左= =,!=8左&9左10左|11左&12左|13左?:14右=15右大家不必硬记这些优先级,可以通过针对容易混淆的地方加括号就可以了,比如有如下的表达式:!i=j,首先是判断两个值是否一样,然后是个取非的操作,我们可以改写成:!(i=j),虽然!的优先级比=要低,加不加括号的效果是一样的,但是如果我们加了括号,看起来就更清除了。2.1.4对象型的数据类型在Java语言里,以类的形式,定义了一些对象类型的数据类型,并且在其中封装了
12、针对这种类型数据的一些操作方法,其中,我们经常会用到的有:基本数据类型的封装类和描述字符串的String类。下表2-4描述了基本数据类型对应的封装类。表2-4 基本数据类型对应的封装类基本数据类型对应的封装类booleanBooleancharCharacterbyteByteshortShortintIntegerlongLongdoubleDoublefloatFloat各数据类型对应的封装类里,不仅包括了基本数据类型的数据,由于它们更是类,所以会封装了一些实用的方法,比如我们在如下的代码里,通过Integer类封装的doubleValue方法,把Integer类型的数据转换成double
13、。Integer k = new Integer(10);k.doubleValue();封装类等于基本数据类型加针对基本数据类型的操作,它们是对象,这点对我们来说至关重要。在Java语言里,描述字符串的String类有着很重要的用途,在这个类里,同样是定义了针对字符串的一些操作,通过下面的StringTest.java代码,我们可以看到String类的一些常用方法。public class StringTest public static void main(String args) String s1 = Hello World;String s2 = new String(Hello W
14、orld);/输出字符串的长度System.out.println(the length of s1 is + s1.length();/得到第三个字符,索引位置从0开始char index2 = s1.charAt(2);System.out.println(index2);/比较两个字符串 错误的做法if(s1 = s2) System.out.println(The two String are equal!); else System.out.println(The two String are not equal!); /比较两个字符串 正确的的做法if(s1.equals(s2)
15、System.out.println(The two String are equal!); else System.out.println(The two String are not equal!); /连接字符串s1 = s1.concat(!);System.out.println(After concat the s1 is + s1);/查找字符串的位置System.out.println(s1.indexOf(!);System.out.println(s1.indexOf(#);在上述的方法里,我们针对字符串做了如下的操作:1. 首先定义了两个字符串,我们可以通过直接赋值,也可
16、以通过以new的方式调用String的构造函数来创建String类型的对象。2. 通过length方法可得到字符串的长度,执行到这里,会输出如下结果。the length of s1 is 113. 通过charAt方法可得到字符串里指定索引位置的char类型变量,因为索引位置从0开始计算,所以执行到这里,会输出s1对象的第三个索引位置的“l”。4. 下面,我们将要比较s1和s2两个字符窜是否相等,首先用的是=的方式,这里我们可以发现,虽然两个字符串的内容完全相等,但是,从随后输出的内容上来看, s1=s2的结果是false。这是个初学者经常会犯的错误!因为s1和s2都是对象,所以=操作符是用
17、来判断这两个对象的引用地址(即这两个对象在内存里的存储首地址)是否相等,而不是判断它们的内容是否相等。所以,我们要用equals方法来判断两个String类型的对象里的值之否相等。5. 可以通过concat方法,连接两个字符串,代码里我们是把!加到了Hello World的后面,我们可以通过输出看到”Hello World!”的效果。6. 可以通过indexOf方法,来查找指定字符的位置,如果找到,这个方法将返回这个字符的索引位置(索引位置同样是从0开始),如果没有找到,则返回-1。2.1.5方法(函数)的参数和返回值方法(也叫函数)是Java语法的重要组成部分,它的语法比较简单,但用途比较广
18、泛,通过下面的FunctionTest.java代码,我们一起来学习一下方法的用途。public class FuncionTest /方法定义public static int add(int i,int j)return i+j;public static void main(String args) /方法调用int result = add(2,2);System.out.println(result);首先我们定义了一个add的方法,定义方法的基本语法是:修饰符 返回类型 方法名(参数列表)这里的修饰符是public和static表示公有的静态方法,它的具体含义会在下文里描述,这里的
19、返回类型是int,表示add方法将要返回一个int类型的结果,返回类型可以是基本数据类型,也可以是类,如果这个方法没有返回,则可以用void在表示。这里的方法名是add,参数是两个int类型的值。而在add的方法主体里,是针对了两个输入参数,做了个加的操作,并且通过return语句将结果返回。这里请大家注意,返回结果的类型必须要和方法定义时声明的返回类型相一致。而在main函数里调用add方法时,我们的做法是:int result = add(2,2);,针对add方法的参数列表,我们传入了两个int类型的参数,并且用了同样是int类型的result变量来接收add方法的返回值。如果我们在ma
20、in函数里有多个add操作,那么可以把这些加法操作定义到方法体里,而不是直接在main函数里执行操作,这样可以减少代码的冗余程度。2.2程序流程控制 流程控制的语句起着控制代码执行顺序的作用,它由顺序、选择、循环这3种最基本的结构组成。通过这种方式得到的代码,结构清楚,层次分明,易于阅读与维护。在这里需要强调的一点是,虽然Java是一种面向对象的语言,我们可以把它的结构模块化,但是模块内部最基础的结构仍是这种面向过程的方式,只不过在整体的设计上我们运用了面向对象的理念。2.2.1顺序与分支 顺序结构是最基本最简单的结构,它按着从上到下的流程顺序的组织代码,在编程的时候我们一般会基于这种顺序结构
21、与分支和循环进行一定的嵌套,从而使代码进行有效地运作。分支结构由if和switch两个关键字引出。前者用于二选一后者用于多种分支情况的选择。if else 结构:if(条件语句)分支语句1;else分支语句2;如果条件语句值为true时,执行分支语句1,否则执行分支语句2。如果需要满足条件时同时执行多条语句,只需把这些语句用“”括起即可。if 结构:if(条件语句)语句;如果条件语句值为true时,执行语句,否则忽略该语句。同样,如果需要满足条件时同时执行多条语句,只需把这些语句用“”括起即可。else if 结构:if(条件语句1)分支语句1;else if(条件语句2)分支语句2;else
22、 if(条件语句n)分支语句n;else分支语句n+1;如果条件语句1为true时,执行分支语句1,否则如果条件语句2为true时,执行分支语句2,否则如果条件语句n为true时,执行分支语句n,否则执行分支语句n+1。通过这种if else语句嵌套的方式达到了多分支语句只执行其中一个分支语句的效果,由于if else在本章里使用最为广泛,所以在这里不再单独举例。switch结构,它的语法是:switch(条件语句)case 值1 : 语句1;case 值2 : 语句2;case 值n : 语句n;default : 语句default;先计算条件语句的值,该值必须为整数型或者字符型,如果值为
23、1,执行语句1,如果值为2,执行语句2,如果值为n,执行语句n,如果所有的值都不匹配就执行语句default,default段也可以省略掉。需要注意的是条件语句的值在与某一个值匹配执行了相应的语句之后,如果没有break语句打断,则程序会继续执行下去直到遇到了一个break语句或者switch结束。例如:char flag = b;int i=1;switch(flag)case a : i = 1;case b : i = 2;break;case c : i = 3;default : i = 4;上述代码的业务逻辑是,如果flag的值为a,则先执行i = 1,然后是i = 2,此时遇到了
24、break才会跳出switch语句。如果flag的值为b,则执行i = 2,此时遇到了break跳出switch。如果flag的值为c,则执行i = 3,然后执行i = 4,最后跳出switch。如果flag不是其中的任何一个则执行i = 4,然后跳出。2.2.2循环流程 循环流程实现了一种反复执行某段程序的流程结构。它是由循环语句和跳转语句共同实现的。循环语句包括for、while、do-while语句,跳转语句包括break、continue语句。for语句:for(初始化语句;条件语句;递归语句)循环体;程序先执行初始化语句,它的作用是初始化循环变量,如果有多个语句就逗号隔开,然后判断条
25、件语句的值,如果为true执行循环体和递归语句,再判断此刻的条件语句的值,重复以上步骤,直到某次递归之后,条件语句的值为false,跳出当前for语句。例如:while语句:while(条件语句)循环体;判断条件语句的值如果为true,执行循环体,再判断此刻的条件语句的值,重复以上步骤,直到条件语句的值为false,跳出当前while语句。do-while语句:do循环体;while(条件语句)先执行循环体,然后判断条件语句的值如果为true继续执行循环体,再判断条件语句的值,重复以上步骤,直到条件语句的值为false,跳出当前do-while语句。break语句:可以用于switch语句和以
26、上3种循环语句,目的是跳出整个循环语句。continue语句:用于以上3种循环语句,目的是跳出当前的一次迭代,而不是跳出整个循环语句,这是它与break最大的区别。2.2.3有争议的goto语句做过BASIC或C语言编程的人都知道goto语句是一个臭名昭著语句,它可以让代码跳转到任何的位置,它增加了代码的复杂度,严重影响了程序的可读性,因此使用的时候应该谨慎。在Java里面goto作为一个保留字存在,但没有拿来做任何用途但是Java里面的break、continue结合循环语句中的label实现了部分的goto跳转功能。在多层循环的嵌套中怎样从内层循环直接跳出外层循环的迭代哪,让我们看一下下面
27、的代码Lable.java。public class Label public static void main(String args) int i = 0;outer: while (true) System.out.println(in while loop);while (true) i+;System.out.println(i = + i);if (i = 2) System.out.println(continue outer);continue outer;if (i = 4) System.out.println(break outer);break outer;在Eclip
28、se中运行该程序得到如下输出:in while loopi = 1i = 2continue outerin while loopi = 3i = 4break outer该程序先初始化变量i值为0,然后进入了最外层循环,并且在该循环的前面加入了一个名字叫做outer的标签,然后打印“in while loop”,进入内循环,i值加一变为1,然后内部循化迭代i值加一变为2,此时满足if条件语句打印“continue outer”并执行continue outer语句,从内层的一次迭代跳到了外层循环的迭代,注意这种方式只有通过标签才能实现,然后继续进入内层循化,当i值变为4时打印“break o
29、uter”并执行break outer语句,曾内层的一次迭代跳出了整个外层循环,程序执行结束,这种直接跳出的方式也只有标签可以实现。2.2.4使用If语句判定是否是闰年 计算机之所以如此流行,最主要的原因就是它给人们的日常生活带来的极大的方便。下面给大家展现一个比较有趣的例子:如何用if语句判断某一年是否是闰年,请看代码LeapYear.java。public class LeapYear public static void main(String args) int year = 2008; if (year % 4 = 0 & year % 100 != 0) | (year % 400
30、 = 0) System.out.println(year + is a leap year.); else System.out.println(year + is not a leap year.); 在Eclipse中运行该程序得到如下输出:2008 is a leap year.这段代码的业务逻辑是:如果输入年份能够被4整除并且不被100整除或者能被400整除,该年份就是闰年,否则不是。在LeapYear.java代码中我们通过if语句和算术运算、逻辑运算结合在一起非常方便的实现了该功能。2.2.5使用循环语句计算阶乘计算机语言在数学领域也发挥着举足轻重的作用,比如说如何快速的计算整数
31、n的阶乘,请看代码Factorial.java。public class Factorial public static void main(String args) int f = 1;for (int n = 10; n 1; n-) f = f * n; System.out.println(The result is + f);在Eclipse中运行该程序得到如下输出:The result is 程序里,我们可以通过for语句实现计算了n的阶乘,从n开始循环每次都与当前的n相乘把值存放到变量f中,直到n的值减到1为止,这样就达到了计算整数n的阶乘的目的。2.2.6使用Switch语句控
32、制输出 如果我们有多分支选择的需求就可以考虑使用switch语句,比如根据成绩的等级判断具体的分数段,请看代码GradeLevel.javapublic class GradeLevel public static void main(String args) char grade = C; switch (grade) case A: System.out.println(grade + is 85100);break; case B: System.out.println(grade + is 7084);break; case C: System.out.println(grade +
33、is 6069);break; case D: System.out.println(grade + is 0) return true; else return false; public void start()if(checkStatus() = true) System.out.println(Car Start!);else System.out.println(Could not start!);/返回最大时速时的行程数protected int getMaxSpeedLength()/省略一些业务细节/.return maxspeedLength;public class Who
34、leCar public static void main(String args) Car car = new Car();/不正确的一些用法/1 企图访问私有的属性和放法 /car.checkStatus(); /System.out.println(car.innerStatus);/2 企图访问收保护的方法,建议别使用/car.getMaxSpeedLength();/只能访问car里的公有方法car.start() ;在这段代码里,我们首先定义了Car这个类,在其中,用于表示汽车内部状态的innerStatus变量是private的,表示最大时速下的行程数的maxspeedLengt
35、h变量是protected的,这两个变量只在Car类里被用到,在外部是不能使用的。另外,Car里提供了一个public类型的start方法,用户可以通过这个方法开动汽车。在start方法的实现细节里,首先是调用了一个private方法checkStatus来检查汽车内部的状态,只有状态正常,方可启动。我们想象一下,如果用于检测汽车内部状态的checkStatus方法是public类型的,即用户被允许在启动前,通过拆开汽车的线路,直接使用仪器检测内部状态,这样的后果是非常严重的,一方面容易破坏汽车,另一方面会直接威胁用户的生命,此类的严重后果可以通过类的封装性来避免。在Car里还提供了一个pro
36、tected类型的方法,这个方法供它的“赛车”子类使用。在WholeCar的main方法里,我们首先初始化了一个Car类的实例,此后,我们企图访问Car类里的private和protected类型的属性和方法,由于这样的动作可能会产生严重的后果,所以Java的编译器直接禁止了此类动作。在main方法里,我们只能通过调用public类型的start方法启动汽车,调用时,虽然在start内部实现了检测汽车内部状态的动作,但使用者是看不到这个检测动作的。除了上述三种修饰符外,如果我们在方法(或属性)前不加任何的修饰符,那Java编译器为给它赋予一个默认的friendly类型的,它的作用范围介于public和protected之间,表示这个方法(或属性)可以被“包”(package)内被使用。我们来总结一下上述的所有修饰符:1. public、protected、private这三种显式的修饰符用于控制方法和属性可见性,friendly是是隐含的,即如果在类、变量等前没加显示的可见性修饰符,那它就是friendly类型的。 2. 子类只能看到父类里的protected(或更高public级别)中的方法和属性,而在类的外部,不能看到类里的privat
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 汽车设计工程师面试技巧与要点
- 轨道交通企业人力资源管理体系建设探索
- 高铁工程建设部长月度工作总结与展望
- 活动风险评估及应对措施
- 长城汽车公司行政支持团队的工作挑战与对策
- 江梦南演讲稿标题
- 演讲稿脸皮厚的好处
- 2026年妇产科护理学知识考试题库及答案(共100题)
- 创平安校园的演讲稿
- 2015清华大学演讲稿
- 设备合伙投资协议书
- 急性缺血性卒中再灌注治疗指南(2024版)解读
- 2025年广东惠州市交通投资集团有限公司招聘笔试参考题库附带答案详解
- 合同到期后延长期限的补充协议5篇
- 化妆品内包材清洁消毒验证方案
- 外墙真石漆协议书范本
- 公务员-强烈逻辑推理500题
- 2025年中国邮政集团有限公司福建省分公司招聘笔试参考题库含答案解析
- 幼儿园入学准备教育指导要点
- 下肢深静脉血栓护理
- 胸痛早期识别及护理
评论
0/150
提交评论