Skip to content

Commit

Permalink
#4 语法高亮
Browse files Browse the repository at this point in the history
  • Loading branch information
nobodxbodon authored Nov 13, 2017
1 parent 4053280 commit e2056d6
Showing 1 changed file with 40 additions and 40 deletions.
80 changes: 40 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Java入门代码用中文写更能被新手理解, 可惜没有看到类似教

新建文本文件,命名为"问好.java".输入最简单的一个Java程序:

```
```java
class 问好 {
public static void main (String[] 参数) {
// 待续: 要让它做的事
Expand All @@ -74,7 +74,7 @@ class 问好 {

这个程序可以编译运行(见"手把手"部分),但运行后没有任何输出.因为这个程序是个空架子,没有任何可以看到的运行结果.下面就让它做点事.

```
```java
class 问好 {
public static void main (String[] 参数) {
// 要让它做的事
Expand Down Expand Up @@ -131,7 +131,7 @@ $ java 问好
## 四 用Java算术

新建文件"四则运算.java"
```
```java
class 四则运算 {
public static void main (String[] 参数) {
System.out.println(1+2);
Expand All @@ -144,7 +144,7 @@ class 四则运算 {
恭喜! 你已经可以用Java程序完成数学运算了.

那么其他的运算呢? 新建文件"根号.java"
```
```java
class 根号 {
public static void main (String[] 参数) {
System.out.println(Math.sqrt(4));
Expand All @@ -155,16 +155,16 @@ class 根号 {
应该不用啰嗦了,试试把4改成其他的数,看看结果如何?

现在,你可能已经觉得程序的"回答"太"精简"和生硬了,那么人性化一些吧,下面开始只列出main方法内的代码
```
```java
System.out.println("4的平方根是" + Math.sqrt(4));
```
输出听起来顺耳些了,但如果想要把4改成其他数,需要改程序的两个地方,这种麻烦可要不得! 可以把4先存到一个变量里,然后在两处引用同一个变量:
```
```java
int= 4;
System.out.println(数 + "的平方根是" + Math.sqrt(数));
```
这样只要改一处了.不过,为了改输入值,还是要改程序,再编译再运行,这种麻烦可要不得! "参数"终于派上用场了.
```
```java
int= Integer.parseInt(参数[0]);
System.out.println(数 + "的平方根是" + Math.sqrt(数));
```
Expand All @@ -184,7 +184,7 @@ Math是Java自带标准库中的数学类,包含很多有用的方法.详细请

标准库有很多有用的类. 比如随机数, 用在很多聊天机器人上.
新建"随机数生成器.java":
```
```java
class 随机数生成器 {
public static void main (String[] 参数) {
java.util.Random 生成器 = new java.util.Random();
Expand All @@ -199,7 +199,7 @@ java.util.Random是随机数类的全路径, java.util是它所在的包. 没有
nextInt是产生一个随机数的方法. 为什么Math.sqrt和Integer.parseInt不用new出一个个体呢? 因为它们和main方法一样, 都是静态(static)的.

这样重复类的全名看着真累, 下面用import来开头导入这个类路径, 之后就不用再重复了:
```
```java
import java.util.Random;

class 随机数生成器 {
Expand All @@ -216,7 +216,7 @@ class 随机数生成器 {

在上一讲的"根号"类中,用了一个整数(int)变量来保存输入值. "参数"是一个字符串(String)数组.
Java中还有其他几种基本变量: boolean, char, byte, short, long, float, double
```
```java
boolean 年纪尚幼 = true; // true或false,真或假
char= ''; // 单个字符
byte 年龄 = 27; // 字节: -128到127, 即-2^7到(2^7-1)
Expand All @@ -231,7 +231,7 @@ double 体重 = 999999999999.9; // 双精度浮点数: 2^-1074到(2-2^-52)*2^102
上一讲的四则运算类中,已经尝试了4种运算符. 变量运算的结果可以赋给自己,或者另一个变量.

举个例子, 如2岁的时候认识一个字,每年增加两倍, 3年之后会变成多少.下面是一个很直白的计算方法:
```
```java
class 识字类 {
public static void main (String[] 参数) {
int 识字量 = 1;
Expand Down Expand Up @@ -268,7 +268,7 @@ class 识字类 {

那么反斜杠又是个特殊符号了, 如果要显示它, 就需要再加一个: \\\\
类似的还有\t(制表符), \n(换行)等等. 如果将来有一个想不出怎么显示的东西, 再找本工具书看看Java特殊字符部分吧. 下面的程序演示一些:
```
```java
class 特殊字符 {
public static void main (String[] 参数) {
System.out.println("边检员看了看证件,头没抬地说\t\"这么久没回了啊?\".\n百感交集,咧着嘴回了一句\t\"是啊,还没完呢\"");
Expand All @@ -278,7 +278,7 @@ class 特殊字符 {
前几讲已经用过加号连接多个字符串,以及其他类型的变量. 只要是基本变量,都可以这样和字符串用加号连接,产生一个新的字符串.

字符串有不少常用方法,比如获取长度,搜索子字符串,变换英文大小写等等.下面演示他们的用法:
```
```java
class 字符串方法 {
public static void main (String[] 参数) {
String 字符串 = "去是go";
Expand All @@ -293,7 +293,7 @@ class 字符串方法 {

## 七 如果...就...不然...
代码说了算:
```
```java
if (年龄 < 20) {
System.out.println("没到法定婚龄! 等几年再结婚吧");
} else {
Expand All @@ -308,7 +308,7 @@ Java支持所有数学中的大小比较符号: < > >= <=
另外, 因为单个=被用于变量赋值, 判断"等于"就用了双等号: == 不等于呢? !=

如果有并列的多个条件,可以串起来这样写:
```
```java
if (年龄 < 5) {
System.out.println("这是哪家闺女啊?爸妈在哪儿呢?");
} else if (年龄 < 20) {
Expand All @@ -318,7 +318,7 @@ if (年龄 < 5) {
}
```
如果把 <5 和 <20的顺序倒过来:
```
```java
if (年龄 < 20) {
System.out.println("没到法定婚龄! 等几年再结婚吧");
} else if (年龄 < 5) {
Expand All @@ -331,7 +331,7 @@ if (年龄 < 20) {
是的,计算机执行程序就是这么老(si)实(ban), 执行第一个被满足的条件之后的{}内代码, 而且无视后面所有else的条件判断.

注意: 不同于数值的比较方法, 字符串的"等于"判断有自己的方法equals, 比大小用compareTo:
```
```java
if ("辛苦".equals("不辛苦")) {
System.out.println("辛不辛苦无所谓");
} else if ("辛苦".compareTo("不辛苦") > 0){
Expand All @@ -348,7 +348,7 @@ if ("辛苦".equals("不辛苦")) {
记得算识字量的程序么? 如果要算10年, 难道必须重复10行`识字量 = (1 + 每年翻倍数) * 识字量;`吗? 用脚趾想也不可能吧.

在写代码之前, 不妨先构思一下该怎么算. 这里多了一个输入值: 年限. 照原来的思路应该是: 每过一年增加一次识字量, 直到过了10年. 这样就需要记着过了多少年. 之前提到, 一个变量用来"记"变化的值最合适:
```
```java
for (int 年份 = 0; 年份 < 年限; 年份 = 年份 + 1) {
识字量 = (1 + 每年翻倍数) * 识字量;
}
Expand All @@ -359,7 +359,7 @@ for (int 年份 = 0; 年份 < 年限; 年份 = 年份 + 1) {
- 3 "年份"加一, 继续执行第2步

同样的循环用while的格式来写是这样:
```
```java
int 年份 = 0;
while (年份 < 年限) {
识字量 = (1 + 每年翻倍数) * 识字量;
Expand All @@ -369,7 +369,7 @@ while (年份 < 年限) {
看起来for循环更紧凑, 也更不容易写错. while循环里,如果忘写了"年份 = 年份 + 1;",可就有趣了,因为年份没有增加, 循环中止条件一直不能满足(0永远小于年限), 代码运行停不下来,俗称"死循环". 而for循环里因为定了"(初始化; 循环条件; 累加或递减执行语句)"的格式, 少了一项会很扎眼.

如果想要提前结束循环,可以用break. 想知道过几年能认识中文的常用三千字的话:
```
```java
int 年份 = 0;
while (年份 < 年限) {
if (识字量 > 3000) {
Expand All @@ -383,7 +383,7 @@ System.out.println(年份 + "年后认识" + 识字量 + "个字");
break执行后,它所在的循环就被打断,程序从循环之后开始执行.

如果想要循环继续执行,但是跳过循环内的部分代码,可以用continue. 一个牵强的例子,如果从第三年才开始认识新字(比如在国外呆了三年):
```
```java
for (int 年份 = 0; 年份 < 年限; 年份 = 年份 + 1) {
if (年份 < 3) {
continue;
Expand All @@ -400,12 +400,12 @@ for (int 年份 = 0; 年份 < 年限; 年份 = 年份 + 1) {

我们都是人类,每个人都是一个个体,大多数人有共有的属性和行为,同时也存在个体之间的差异.
下面就来在程序里定义一个"人"类:
```
```java
public class 人 {
}
```
这样的"人"还什么都做不了. 我们出生后都有姓名,那么它也应该有:
```
```java
public class 人 {
String 姓名 = "无名氏";

Expand All @@ -416,7 +416,7 @@ public class 人 {
```
这个类具有了"姓名"属性, "自我介绍"方法引用了这个属性并输出加工后的回答.
class前的public表示"人"可以在其他类里使用. 比如这个"世界"类里, "我"是"人"类的一个个体:
```
```java
class 世界 {
public static void main(String[] 参数) {
人 我 = new 人();
Expand All @@ -425,13 +425,13 @@ class 世界 {
}
```
不过,应该有个像样的名字,而不是默认的"无名氏". 需要在自我介绍之前,先定名字:
```
```java
.姓名 = "小白";
```
编译运行"世界"后,可以看到输出.

这个世界好像太单调了,人有不同分类,大人,小孩等等,他们做不同的事.新建"大人"类:
```
```java
public class 大人 extends 人 {
String 责任 = "扶老携幼";

Expand All @@ -441,7 +441,7 @@ public class 大人 extends 人 {
}
```
再新建"小孩"类:
```
```java
public class 小孩 extends 人 {
String 想做的事 = "大人的事";

Expand All @@ -451,7 +451,7 @@ public class 小孩 extends 人 {
}
```
现在的世界要喧闹一些了:
```
```java
class 世界 {
public static void main(String[] 参数) {
大人 大白 = new 大人();
Expand All @@ -474,7 +474,7 @@ class 世界 {
## 十 让它更像人

一个人还有很多属性:
```
```java
public class 人 {
String 姓名 = "无名氏";
int 年龄 = 0;
Expand All @@ -487,7 +487,7 @@ public class 人 {
}
```
谁的小秘密都不可以直接让别人知道. private就限制了这个变量只能给个体内部使用, 任何其他类里,都不能直接获取这个值. 下面这个程序在编译会报错:
```
```java
class 世界 {
public static void main(String[] 参数) {
人 我 = new 人();
Expand All @@ -496,7 +496,7 @@ class 世界 {
}
```
既然这个小秘密只能由自己引用和修改, 一般有公开方法可以让其他类间接接触这个变量:
```
```java
public String 回答(String 听到的) {
if (听到的.contains("?")) {
return "你猜? 答案长度是" + 小秘密.length();
Expand All @@ -513,20 +513,20 @@ public String 回答(String 听到的) {
这个方法返回(return)一个字符串. 可以在"世界"类里打印出每个回答.

在创建个体的时候, 之前都是new xxxx(), 没有传入任何参数. 因此如果在创建后对属性初始化就需要这样做:
```
```java
大人 大白 = new 大人();
大白.姓名 = "大白";
大白.年龄 = 30;
```
另一种比较简洁的方法是, 在"大人"类里定义一个带参数的创建方法:
```
```java
public 大人(String 姓名, int 年龄) {
this.姓名 = 姓名;
this.年龄 = 年龄;
}
```
然后在创建"大人"个体时,就可以这样:
```
```java
大人 大白 = new 大人("大白", 30);
```
同样可以在"小孩"类里定义一个类似的创建方法. 黏贴复制的很愉快吧? 不过每当这样愉快的时候,就需要警惕一下,因为重复的代码往往意味着设计问题,而且很可能增加今后代码维护的难度. 一个不成文的经验是, 重复代码越少越好.
Expand All @@ -539,7 +539,7 @@ public String 回答(String 听到的) {
## 十一 数据排排站-数组

第四讲里, 已经用过了"参数"这个字符串数组. 下面我们用数组给人排队:
```
```java
class 排队 {
public static void main(String[] 参数) {
人[] 一队 = {
Expand All @@ -560,7 +560,7 @@ class 排队 {
注意: 数组的序号是从0开始的, 这是比Java年纪还大的一个老传统, 再配合一下吧.

数组还有另一种初始化方法:
```
```java
人[] 二队 = new 人[10];
二队[0] = new 人("阿狗", 11);
二队[1] = new 人("阿猫", 10);
Expand All @@ -570,15 +570,15 @@ class 排队 {
很直白, 一开始是初始化一个长度是10的数组, 之后就是往数组中的指定位置放个体.

如果对二队按照一队的方式来"报数", 会报错NullPointerException,因为位置2还空着. 这时需要加个"不为空"的判断条件:
```
```java
for (int 序号 = 0; 序号 < 二队.length; 序号++) {
if (二队[序号] != null) {
二队[序号].自我介绍();
}
}
```
排了队, 下面就试试按照某个属性排序. 比如要按年龄对一队排序. 大略的思路可能是: 比较相邻的两人年纪,谁小就排在前面. 下面是Java对应这种思路的一种程序:
```
```java
java.util.Arrays.sort(一队, new java.util.Comparator<人>() {
@Override
public int compare(人 甲, 人 乙) {
Expand All @@ -589,7 +589,7 @@ class 排队 {
Arrays和Comparator都是java.util包里的类. 如果嫌这样不美观可以在程序前import这两个类.

如果想要排个方阵呢? 只要再加一对[]就可以了:
```
```java
人[][] 方阵 = new 方阵[10][15];
方阵[0][0] = new 人("阿狗",3);
方阵[2][4] = new 人("阿猫",4);
Expand Down Expand Up @@ -624,7 +624,7 @@ Arrays和Comparator都是java.util包里的类. 如果嫌这样不美观可以
第四讲里, 用到了Integer.parseInt方法. 如果参数输错, 比如"啊呜",运行后会打印出一堆诡异的东西, 其中有NumberFormatException, 也提到"啊呜". 不用懂英文也能猜到这个输入有点问题了.

这个NumberFormatException属于Exception, 俗语叫"异常", 但直译是"例外", 感觉后者的字面意思明确些. 比如这个把字符串转换成整数的方法, "啊呜"对它来说就是个束手无策的例外情况, 拿到手里既然处理不了就会把它"丢"出来. 丢出来就得"接住", 不然像前面那样就砸了. 下面的try ... catch 就是"试试看...接住(例外情况)...":
```
```java
int= 0;
try {
= Integer.parseInt(参数[0]);
Expand Down

0 comments on commit e2056d6

Please sign in to comment.