@Darcy
2017-08-11T11:14:12.000000Z
字数 10238
阅读 2883
JavaForKids
你可以为你程序中一行特定的代码、方法或类添加任意的文本作为注释。因为有时人们会忘记自己以前为什么 写下这些代码,同时也可帮助别人理解你的代码。
Java里,共有三种不同的注释:
//
开头:
// 这个方法用来计算距离
/* 和 */
之间,例如:
/*接下来的 3 行用来存储
鱼的位置
*/
javadoc
的特殊程序,它可以提取你程序中的注释到一个单独的帮助文件。这个文件可以作为你的程序的技术文档。这一类型的注释放在符号/** 和 */
中。这一类型的注释应该只在描述类或方法等这些比较重要代码时才使用。
/**
这个方法根据价格来计算折扣
如果价格超过100元,那么折扣就是 20%
其他情况下,则只有 10%
*/
从现在起,我会在代码示例中加入注释,好让你了解怎样使用和在哪里使用它们。
生活中,我们经常需要做出某些判断:如果她告诉我这个,我就会回答她,否则,我将做其他一些事。Java用 if
语句来检查一个特定的表达式成立与否。成立是 true
,否则是false
。
根据表达式的结果,程序将会分叉执行。
例如,如果表达式我要不要去奶奶那?计算结果是 true
,那么转左;否则转右。
如果一个表达式返回true
,JVM将执行第一个大括号中的代码,否则执行else
后的语句。举个例子,如果价格(price)超过100元,则给予20%的折扣,否则只有10%。代码实现如下:
// 价格超过100元的物品给20%的折扣
if (price > 100){
price=price*0.8;
System.out.println("You’ll get a 20% discount”);
}else{
price=price*0.9;
System.out.println("You’ll get a 10% discount”);
}
让我们修改一下Fish
中的方法 dive()
,以确保我们的鱼不会潜入超过100英尺深:
public class Fish extends Pet{
int currentDepth=0;
public int dive(int howDeep){
currentDepth=currentDepth + howDeep;
if (currentDepth > 100){
System.out.println("I am a little fish and " + " can't dive below 100 feet");
currentDepth=currentDepth - howDeep;
}else{
System.out.println("Diving for " + howDeep + " feet");
System.out.println("I'm at " + currentDepth +" feet below the sea level");
}
return currentDepth;
}
public String say(String something){
return "Don't you know that fish do not talk?";
}
}
现在,对FishMaster做些小小的修改并让我们的鱼潜入深海:
public class FishMaster {
public static void main(String[] args) {
Fish myFish = new Fish();
//试着让鱼下潜到比100尺更深的地方
myFish.dive(2);
myFish.dive(97);
myFish.dive(3);
myFish.sleep();
}
}
运行程序,它将打印如下信息:
Diving for 2 feet
I'm at 2 feet below the sea level
Diving for 97 feet
I'm at 99 feet below the sea level
I am a little fish and can't dive below 100 feet
Good night, see you tomorrow
有时候,你需要检查多个条件来做出决定,比如,如果州 (state)名是Texas或者California的话,那么就为商店的每一件商品加上州税。这是一个逻辑‘或’(or)
的例子 - Texas 或者 California。在Java中,逻辑‘或’
的符号是一根或者两根的竖线。它工作原理是这样子的:如果其中的一个条件为true
,那么整个结果就是true
。在下面的例子中,我会使用String
类型的变量来进行比较,它有一个equals()
方法,可以比较两个字符串是否相等,在这里用它来比较州名否等于Texas或者California:
if (state.equals("Texas") | state.equals("California"))
你也可以在if语句里面使用两条竖线:
if (state.equals("Texas") || state.equals("California"))
它们两者的区别在于:如果你使用两条竖线,那么只要第一个表达式(state.equals("Texas"))
的结果为true
,那么第二个表达式就不会执行检查了。如果是单条竖线的方式,那么JVM会对这两个表达式都进行检查。
逻辑‘与’(and)
是用一个或者两个的&
符号来表示的,它工作原理是这样子的:如果其中所有的表达式的结果为true
,那么整个结果就是true
。举个例子:当州名(state)是New York 并且 价格(price)大于110美元的时候,需要交纳销售税。也就是这两个条件要同时成立:
if (state.equals("New York") && price >110)
或者
if (state.equals("New York") & price >110)
如果你使用的是两个&
符号的方式,那么当第一个表达式结果是false
时,则第二个表达式就不用执行检查了,因为无论第二个表达式的结果如何,它总的结果反正都是false
的。如果是单个符号&
的方式,就算第一个结果是false
,那么第二个表达式还是会执行的。
逻辑‘非’
是用感叹号!
来表示的,它的作用是会使结果相反。例如:如果你想当州名不是New York的情况执行一些操作,那么你可以使用下面的语句:
if (!state.equals("New York"))
这里展示的另外一个例子 - 下面的两个表达式的效果是一样的:
if (price < 50)
if (!(price >=50))
if
语句还有另外一种表示方法条件操作符( conditional operator) 。这种语句用于给一个变量赋值, 其中问号会紧跟在判断表达式的后面。如果这个表达式成立,那么就给在左边的这个变量赋予跟在问号?
后面的值,否则就给它赋予跟在冒号:
后面的值:
discount = price > 50 ? 10 : 5;
如果price
比50大,那么赋予discount
这个变量10的值,否则为5。这其实就是用更简短的方式代替了一个常规的if
语句:
if (price > 50){
discount = 10;
} else {
discount = 5;
}
你也可以通过使用一些else if
语句块来构建更多复杂的if
语句。这次我们将创建一个新的类叫做ReportCard
。这个类必须有main()
方法以及一个只带单个参数的方法,这个数值类型的参数代表你要传入的成绩。根据数字的不同,它会把你的成绩用A,B,C,D或F来表示。我们将这个方法命名为convertGrades()
。
public class ReportCard {
/**
这个方法带了一个int类型的参数testResult:该方法返回的字母是A、B、C还是D取决于这个参数的值。
*/
public char convertGrades( int testResult){
char grade;
if (testResult >= 90){
grade = 'A';
}else if (testResult >= 80 && testResult < 90){
grade = 'B';
}else if (testResult >= 70 && testResult < 80){
grade = 'C';
}else {
grade = 'D';
}
return grade;
}
public static void main(String[] args){
ReportCard rc = new ReportCard();
char yourGrade = rc.convertGrades(88);
System.out.println("Your first grade is " + yourGrade);
yourGrade = rc.convertGrades(79);
System.out.println("Your second grade is " + yourGrade);
}
}
除了使用else if
条件,这个例子还告诉你怎么使用char
类型的变量。在上面的例子中,你能看到,用 &&
操作符你可以确定一个数字是否落在一定范围内。在Java里,你不能就直接写if(80<=testResult<90)
,而应写成if( 80<=testResult && testResult<90 )
:
testResult >= 80 && testResult < 89
思考一下:在这里我们为什么不能使用 ||
操作符 ?
switch
语句有时可作为if
语句的替代。程序将会根据在switch
后面括号中的值来选择和它相同值的case
代码块来执行:
public static void main(String[] args){
ReportCard rc = new ReportCard();
char yourGrade = rc.convertGrades(88);
switch (yourGrade){
case 'A':
System.out.println("Excellent work!");
break;
case 'B':
System.out.println("Good job!");
break;
case 'C':
System.out.println("You have to work more!");
break;
case 'D':
System.out.println("Change your attitude!");
break;
}
}
可别忘了在每个case
后面加上关键字break
哦,如果没有它,那么接下来的case
都会被执行,直到下个break
出现或直到语句结束。例如,在没有加break
的情况下,yourGrade
的值为'C'
, 那么下面的case 'D'
里面的代码也会被执行。
在Java里switch
语句有一个限制条件--所有需要赋值的变量都必须是以下类型中的其中一种:
char
int
byte
short。
类ReportCard
在方法convertGrades()
里面声明了一个变量--grade
。如果你声明的一个变量在任意一个方法里,那么这个变量就叫做本地变量(local variable)。这意味着只有在这个方法里的代码才能使用这个变量。当这个方法结束,这个变量会自动从内存中清除。程序员通常用作用域(scope)这个词来表示一个变量会存活多久,比如,你可以说在一个方法里被声明的变量有一个局部作用域。
如果一个变量必须被数个方法重复使用,或者它必须出现在同一个类里的不止一个方法里,你应该把这类变量声明在任何一个方法之外。在Fish
这个类里,currentDepth
是一个成员变量。只要Fish
这个对象的实例还驻留在内存里,这些变量都是“活着的”,所以它们也被称为实例变量(instance variables)。它们可以被在这个类里的所有方法共享并使用,而且在某些情况下,它们甚至能出现在外部的类里,比如,在我们构建的类里,System.out.println()
这个 语句中使用了被声明在System
这个类里的out
这个变量。
等一下! 如果我们还未曾为System
类构建一个实例,是否还可以用它里面的成员变量呢?没错,当然可以,只要我们用static
这个关键词来声明这个变量。如果一个成员变量或一个方法的声明以static
开头,你就不必给这个类构建一个实例来使用它。类的静态变量(也称为类变量)将被这个类所有的实例共享,也就是说,这个变量在所有实例中的值都是一样的,在一个实例中改变这个变量的值会直接影响到另外一个实例。
比如在下面的代码中,Fish
有一个静态的类变量,Fish
创建了两个实例fish1
和fish2
,当currentDepth
在fish2
的实例中的值被改为3时,fish1
中的currentDepth
也跟着变成3了。
public class Fish extends Pet{
static int currentDepth = 0;
public static void main(String[] args){
Fish fish1 = new Fish();
fish1.currentDepth = 2;
Fish fish2 = new Fish();
fish2.currentDepth = 3;
//这里的fish1.currentDepth的值是什么呢? 答案就是3啦 :)
System.out.println("the Fish's currentDepth is : "+fish1.currentDepth);
}
}
好了,下面让我们来看看静态的方法吧。
比如,我们把ReprotCard
这个类里的方法convertGrades()
声明为static
类型的,因为它里面的代码并没有使用到类的成员变量,注意,类的成员变量是不能在静态方法中使用的。看看下面这个例子是如何调用一个static
方法的:
char yourGrade = ReportCard.convertGrades(88);
这里有另外一个例子:在Java里有个类叫Math
,它包含了几十种数学方法,比如 sqrt()
, sin()
, abs()
等等。所有的这些方法都是static
类型的,你不需要给Math
这个类构建一个实例来调用它们,比如:
double squareRoot = Math.sqrt(4.0);
Java用new
这个操作符在内存里构建对象的实例,比如:
Fish myFish = new Fish();
在Fish
这个词后面的圆括号告诉我们这个类里有个方法叫做Fish()
。是的,这里有一些特殊的方法叫做构造方法( constructors),它们有如下特征:
void
这个关键词。任何一个类都可以有不止一个构造方法。如果你不给这个类构建一个构造方法,那么Java编译器会为你自动生成一个默认的无参构造方法。所以即使Fish
这个类没有任何的构造方法,Java编译器也不会在诸如new Fish()
此类的语句上出问题的。
通常,构造方法用于给一个类里的成员变量赋予初始值,比如,在下面版本的Fish
类中包含一个带有单个参数的构造方法,它只赋予实例变量currentDepth
这个参数的值,为下一步所用。
public class Fish extends Pet{
int currentDepth;
Fish(int startingPosition){
currentDepth = startingPosition;
}
}
现在FishMaster
这个类可以构建Fish
的一个实例并给这个它赋予一个初始位置。下面这个例子构建了Fish
的一个“潜入”海底20英尺的一个实例:
Fish myFish = new Fish (20) ;
如果在一个类里,一个带有参数的构造方法已经被定义了,你就不能再使用默认无参数构造方法了。如果你想要一个没有参数的构造方法--那就多写一个吧。
public class Fish extends Pet{
int currentDepth;
//没有参数的构造方法
Fish(){
}
//有参数的构造方法
Fish(int startingPosition){
currentDepth = startingPosition;
}
}
当你需要表示某个对象的实例时,关键词this
就能派上用场。看看下面的这个例子:
class Fish{
int currentDepth;
Fish(int currentDepth){
this.currentDepth = currentDepth;
}
}
一个this
关键词就能有效阻止名称重叠导致的冲突,比如,this.currentDepth
指的是Fish
中的成员变量currentDepth
,而currentDepth
指的是参数值。
换句话说, this
就是对Fish
的实例对象自己的引用。
在[第六章: 如何在类之间传递数据]这个章节里,你会看到关于使用关键词this
的另一个重要例子。
假设你的程序必须储存4个游戏玩家的名字。你可以声明一个含有4个元素( element)的String
数组( array String) ,而不是声明4个不同的String
变量。
我们是通过在变量名称或数据类型后面加上方括号来标记数组的:
String[] players;
or
String players[];
这几行其实就是要告诉Java编译器,你将在players
这个数组里储存几个字符串。每一个元素都有它自己的索引,都从0开始。下面这个例子就构建了一个数组的一个实例,它可以储存4个String
元素且给这个数组的所有元素赋值:
players = new String[4];
players[0] = "David";
players[1] = "Daniel";
players[2] = "Anna";
players[3] = "Gregory";
在给一个数组的元素赋值之前你必须知道这个数组的大小。如果你不能事先确定这个数组将有多少元素,你就不能使用数组,而应观察其他的Java的类,比如Vector
,不过现在我们还是先来讨论数组的问题吧。
任何一个数组都有一个叫做length
的属性,可用于“记住”这个数组的元素的数量,因此你总能知道这里一共有多少元素:
int totalPlayers = players.length;
如果在你声明这个数组时,就已经知道所有将被储存在这个数组里的值,你可以一次性声明并初始化这样的数组:
String [] players = {"David", "Daniel", "Anna", "Gregory"};
假设第二个游戏玩家是赢家,而你想要对这个孩子送出祝贺词。如果游戏玩家的名字都被储存在一个数组里,我们就要在代码里写它的第二个元素:
String theWinner = players[1];
System.out.println("Congratulations, " + theWinner + "!");
下面是这个代码的输出结果:
Congratulations, Daniel!
你知道为什么第二个元素的索引是[1]吗?你当然知道,因为第一个元素的索引永远都是[0]。
在这个例子里游戏玩家的这个数组是一维的,因为我们把他们储存在一行里。如果我们想把这些值储存在一个矩阵里,我们可以构建一个二维数组。Java允许构建多维数组。你可以在数组里储存任何对象,在第十章里我会告诉你怎么做。
循环用于多次重复一个相同的动作,比如,我们需要对多个游戏赢家发出祝贺词。
如果你知道循环重复的次数,那么可以用关键词for
来使用循环:
int totalPlayers = players.length;
int counter;
for (counter=0; counter<totalPlayers; counter++){
String thePlayer = players[counter];
System.out.println("Congratulations," + thePlayer+"!");
}
Java虚拟机(JVM)执行在大括号之间的每一行代码,然后返回到循环的第一行,给counter
变量增加1并判断条件表达式是否成立。以上代码表达的含义如下:
输出编号和
counter
的当前值相同的数组元素的值。从编号为0的元素(counter=0
)开始,给counter
的值增加1(counter++
)。一直重复此动作,直到counter
等于totalPlayers
为止(coutner=totalPlayers
)。
在编写循环代码时还可以用另一个关键词--while
。在这些循环里你不必知道一个动作被重复的确切次数,但你必须知道什么时候该停止循环。下面我们来看看,我们怎么使用while
循环来祝贺游戏赢家,当变量counter
的值跟totalPlayers
的值相等时,这个循环就会停止:
int totalPlayers = players.length;
int counter=0;
while (counter< totalPlayers){
String thePlayer = players[counter];
System.out.println("Congratulations, "+ thePlayer + "!");
counter++;
}
在第九章你将会学习如何在磁盘上储存数据并把它们读取到内存中。如果你从磁盘文件里读取游戏分数,你就不能事先确认被储存在那儿的分数有多少。那么,你很可能会用while
循环来读取分数。
使用循环时,你也可以使用两个重要的关键词:break
和continue
。
当某些特定条件成立(true
)的时候,关键词break
可用于跳出循环。假设不管我们有多少个游戏玩家,我们最多只想送出3次祝贺词。在下面的例子中,在显示了数组元素0、1、2之后,break
会让代码跳出此循环,而程序将继续执行大括号后面的代码。
下面的这个代码在if
语句中有一个双重等号符(==
)。这意味着你在判断变量counter
的值是否等于3 。在这里,一个等号(=
)意味着给变量counter
赋予3的值。在if
语句里用=
代替==
是个会带来棘手的麻烦的错误,它可以导致不可预测的程序错误,且不容易被查找出来。
int counter =0;
while (counter< totalPlayers){
if (counter == 3){
break; // 跳出循环
}
String thePlayer = players[counter];
System.out.println("Congratulations, "+thePlayer+ "!");
counter++;
}
关键词continue
能让代码跳过下面的代码并返回到循环的开头。假设你想祝贺除了David以外的每一个游戏玩家--关键词continue
会让程序返回到循环的开头:
while (counter< totalPlayers){
counter++;
String thePlayer = players[counter];
if (thePlayer.equals("David"){
continue;
}
System.out.println("Congratulations, "+ thePlayer+ !");
}
while
循环还有另一种表示方式,是以do
开头的,例如:
do {
// 要循环的代码
} while (counter< totalPlayers);
这种循环会在执行大括号之间的代码之后再进行判断一个表达式是否成立,这意味着在循环里的代码会被执行至少一次。而以关键字while
开头的循环,如果一开始表达式不成立,那么循环体里面的代码就一次都不会被执行了。
jGuru:语言概要.短课程:
http://java.sun.com/developer/onlineTraining/JavaIntro/contents.html
变量的作用域:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/scope.html
TemperatureConverter
的新的类,而且它的一个方法有下面这样的签名:
public String convertTemp(int temperature, char convertTo)
如果参数convertTo的值是F,那么温度就必须被转换为华氏温度,同理,如果它的值是C,那么就转换为摄氏温度。当你调用这个方法的时候,可以用加上单引号为char类型的参数传值,如 'C'。
2. 声明类ReportCard
的方法convertGrades()
为类型,并从main()
方法中删除初始化这个类的代码。
continue
的例子里,我们把counter++
移到上面去了。 break
的例子里一样,会发生什么事情呢?
本著作係採用創用 CC 姓名標示-非商業性-禁止改作 2.5 中國大陸 授權條款授權.