修正全书错别字、术语统一和逻辑错误

This commit is contained in:
2026-06-10 12:59:03 +08:00
parent ca56eedfda
commit fa6dbeb74e
18 changed files with 198 additions and 87 deletions
+19 -19
View File
@@ -1,4 +1,4 @@
danny- [1. How to learn Java?](#1-how-to-learn-java) - [1. How to learn Java?](#1-how-to-learn-java)
- [2. 什么是面向对象?](#2-什么是面向对象) - [2. 什么是面向对象?](#2-什么是面向对象)
- [2.1. 用C来描述一个对象](#21-用c来描述一个对象) - [2.1. 用C来描述一个对象](#21-用c来描述一个对象)
- [2.2. C语言描述圆的总结](#22-c语言描述圆的总结) - [2.2. C语言描述圆的总结](#22-c语言描述圆的总结)
@@ -39,7 +39,7 @@ danny- [1. How to learn Java?](#1-how-to-learn-java)
## 2. 什么是面向对象? ## 2. 什么是面向对象?
对象(Object)这个概念广泛存在于我们的生活当中,一般一个独立的个体,具备一定的特性(properties),并有一定的动作能力(capability)。例如,一个具体的人,具备属性(性别、年龄、升高...);同时具备一定的能力(说话、跑步、工作...) 对象(Object)这个概念广泛存在于我们的生活当中,一般一个独立的个体,具备一定的特性(properties),并有一定的动作能力(capability)。例如,一个具体的人,具备属性(性别、年龄、升高...);同时具备一定的能力(说话、跑步、工作...)
面向对象编程是指把相关数据和函数按照对象的方式进行组织和分类,以便达到便于设计、实现、维护和增加代码重用率的目的。面向对象编程中的类(Class)与对象(Object)与我们常用语境中的概念有所不同,我们在学习的过程中注意区分。 面向对象编程是指把相关数据和函数按照对象的方式进行组织和分类,以便达到便于设计、实现、维护和增加代码重用率的目的。面向对象编程中的类(Class)与对象(Object)与我们常用语境中的概念有所不同,我们在学习的过程中注意区分。
@@ -47,7 +47,7 @@ danny- [1. How to learn Java?](#1-how-to-learn-java)
### 2.1. 用C来描述一个对象 ### 2.1. 用C来描述一个对象
我们以一个简单的例子来分析面向对象,这个例子是描述平面中的一个圆。这里我们需要两组参数来描述圆,第一个参数是坐标位置(X、Y);另外一个是圆本的描述,例如大小(半径r),可能还有颜色等等,简单来说,我们目前只有半径。 我们以一个简单的例子来分析面向对象,这个例子是描述平面中的一个圆。这里我们需要两组参数来描述圆,第一个参数是坐标位置(X、Y);另外一个是圆本的描述,例如大小(半径r),可能还有颜色等等,简单来说,我们目前只有半径。
如果从C语言出发,需要建立一个结构体来描述圆。 如果从C语言出发,需要建立一个结构体来描述圆。
@@ -94,7 +94,7 @@ void setCircle(struct Circle *c, float x, float y, float r) {
} }
``` ```
另外我们一次性打印整个圆的数据,这样我们最好需要一个函数。 另外我们需要一次性打印整个圆的数据,因此最好需要一个函数。
```c ```c
/** /**
@@ -157,7 +157,7 @@ int main() {
1. 圆的结构体描述是一个抽象的描述,因为结构体是类型定义,并没有与其对应的变量;这儿描述和后面的Java类的定义很像。 1. 圆的结构体描述是一个抽象的描述,因为结构体是类型定义,并没有与其对应的变量;这儿描述和后面的Java类的定义很像。
2. 声明一个结构体变量后就有一个真实的内存变量来描述一个特定的圆了,这个变量是圆(抽象描述的)一个实例(实体),也叫做对象;这个概念和Java的对象非常相似; 2. 声明一个结构体变量后就有一个真实的内存变量来描述一个特定的圆了,这个变量是圆(抽象描述的)一个实例(实体),也叫做对象;这个概念和Java的对象非常相似;
3. 通过点(.)或者(->)可以操作结构体变量(对象)内部的成员,这点和Java对象的操作也非常相,只不过Java都是用点(.) 3. 通过点(.)或者(->)可以操作结构体变量(对象)内部的成员,这点和Java对象的操作也非常相,只不过Java都是用点(.)
这里我们发现,操作结构体的函数是独立定义的,并且需要把结构体变量作为参数进行传递。圆这个结构体是死的,需要外部的函数来对其进行操作。如果把圆这个结构体变量和生活中的对象联系起来,会有些有趣的事情。 这里我们发现,操作结构体的函数是独立定义的,并且需要把结构体变量作为参数进行传递。圆这个结构体是死的,需要外部的函数来对其进行操作。如果把圆这个结构体变量和生活中的对象联系起来,会有些有趣的事情。
@@ -187,7 +187,7 @@ c1.print(); // C语言无法做到
### 2.3. 使用Java来实现 ### 2.3. 使用Java来实现
接下来我们使用java来实现上述的功能,这里主要是要把相关的函数作为结构体的一个部分。 接下来我们使用Java来实现上述的功能,这里主要是要把相关的函数作为结构体的一个部分。
```c ```c
/** /**
@@ -256,7 +256,7 @@ javac Circle_Test.java
发现生成了两个文件 发现生成了两个文件
![](img/20230302094127.png) ![](img/20230302094127.png)
这两个class文件是java编译后的文件,类似Windows中的exe文件。但是这个文件不能直接运行,需要在Java虚拟机(VirtualMachine)中运行。 这两个class文件是Java编译后的文件,类似Windows中的exe文件。但是这个文件不能直接运行,需要在Java虚拟机(VirtualMachine)中运行。
接下来使用命令行 接下来使用命令行
@@ -275,7 +275,7 @@ The position x=1, y=1, radius=3.300000!
**文件名必须是 Circle_Test.java,这个文件名的主文件名必须和源文件中 public class Circle_Test {...} 的类名保持一致。** **文件名必须是 Circle_Test.java,这个文件名的主文件名必须和源文件中 public class Circle_Test {...} 的类名保持一致。**
**javac是编译命令,java是运行命令(使用java虚拟机运行编译后的代码)。关于虚拟机下面会讲到。** **javac是编译命令,java是运行命令(使用Java虚拟机运行编译后的代码)。关于虚拟机下面会讲到。**
## 3. JAVA的特点和历史 ## 3. JAVA的特点和历史
@@ -293,13 +293,13 @@ The position x=1, y=1, radius=3.300000!
![Alt text](img/Java%E8%99%9A%E6%8B%9F%E6%9C%BA.drawio.svg) ![Alt text](img/Java%E8%99%9A%E6%8B%9F%E6%9C%BA.drawio.svg)
这种分层的设计理念我们在很多地方都用到,例如网络的TCP/IP协议层,软件系统当中的分层设计。分层的设计的目的就是为上层提供统一且稳定的服务而隔离下层的不同。从上图知,如果操作系统是Windows,无论硬件是Intel还是AMD,上层的应用都可以不做修改的运行(当然CPU架API: application programming interface JDK: Java Developing Kit IDE: Integrated Development Environment 构需要一致)。而Java的高明之处就在于Java自己有虚拟机,屏蔽了所有下层的不同,只要是Java的应用,在有Java虚拟机的平台上都可以运行。 这种分层的设计理念我们在很多地方都用到,例如网络的TCP/IP协议层,软件系统当中的分层设计。分层的设计的目的就是为上层提供统一且稳定的服务而隔离下层的不同。从上图知,如果操作系统是Windows,无论硬件是Intel还是AMD,上层的应用都可以不做修改的运行(当然CPU架构需要一致)。而Java的高明之处就在于Java自己有虚拟机,屏蔽了所有下层的不同,只要是Java的应用,在有Java虚拟机的平台上都可以运行。
### 3.2. Java的编译和运行 ### 3.2. Java的编译和运行
![](img/20230302095100.png) ![](img/20230302095100.png)
**bytecode是java编译后的二进制代码,只能在java虚拟机上运行。** **bytecode是Java编译后的二进制代码,只能在Java虚拟机上运行。**
### 3.3. 基本概念 ### 3.3. 基本概念
@@ -307,8 +307,8 @@ The position x=1, y=1, radius=3.300000!
#### 3.3.1. JDK、API、IDE #### 3.3.1. JDK、API、IDE
1. API: application programming interface,应用编程接口。Java提供了一套最基本的类,包括文件操作、网络操作、数学运算、输出输出、数据结构等,用来简化你的开发。这些其实是最基本的数据结构和操作函数,只不过Java是按照类(class)的方式来组织的;类比C语言中的标准函数库是按照头文件和C文件来组织的。 1. API: application programming interface,应用编程接口。Java提供了一套最基本的类,包括文件操作、网络操作、数学运算、输出输出、数据结构等,用来简化你的开发。这些其实是最基本的数据结构和操作函数,只不过Java是按照类(class)的方式来组织的;类比C语言中的标准函数库是按照头文件和C文件来组织的。
2. JDK: Java Developing Kit,是Java的开发套件。类比C语言,可以看作是编译器、链接器这些命令行工具。不同的是,Java没有链接,只有编译工具(Javac);另外Java编译后的代码(.class文件,叫做bytecode)不能直接运行,需要使用java虚拟机(java)运行。 2. JDK: Java Developing Kit,是Java的开发套件。类比C语言,可以看作是编译器、链接器这些命令行工具。不同的是,Java没有链接,只有编译工具(Javac);另外Java编译后的代码(.class文件,叫做bytecode)不能直接运行,需要使用Java虚拟机(java)运行。
3. IDE: Integrated Development Environment,这是集成开发环境。一般人不会用写字板和命令行行(Jdk)来开发Java,因为效率太低了。  3. IDE: Integrated Development Environment,这是集成开发环境。一般人不会用写字板和命令行行(Jdk)来开发Java,因为效率太低了。 
## 4. JAVA开发环境 ## 4. JAVA开发环境
@@ -329,7 +329,7 @@ Eclipse 是一个开放的框架,基于Eclipse框架的有很多不同语言
### 4.2. 运行 ### 4.2. 运行
启动Eclipse,出现一个Workspace(工作空间)的选择。工作空间是一个目录,Eclipse在这个目录中可以建立多个项目(Project),每个项目可以包含多个java源代码文件。Eclipse在每次运行的时候会让你选择Workspace,这样Workspace->Project->Source code 就是Eclipse管理源代码的层级关系。 启动Eclipse,出现一个Workspace(工作空间)的选择。工作空间是一个目录,Eclipse在这个目录中可以建立多个项目(Project),每个项目可以包含多个Java源代码文件。Eclipse在每次运行的时候会让你选择Workspace,这样Workspace->Project->Source code 就是Eclipse管理源代码的层级关系。
![](img/20230302095429.png) ![](img/20230302095429.png)
@@ -417,7 +417,7 @@ public class Hello {
} }
``` ```
保存(ctl+s)后,可以运行看看结果: 保存(Ctrl+S)后,可以运行看看结果:
![](img/20230302095908.png) ![](img/20230302095908.png)
@@ -425,7 +425,7 @@ public class Hello {
![](img/20230302095923.png) ![](img/20230302095923.png)
我们看看文件系统中的情况,如上图。包其实对应的就是文件夹。当然一个包中可以再包含子包,如一个文件夹中可以包含子文件夹一样。 我们看看文件系统中的情况,如上图。包其实对应的就是文件夹。当然一个包中可以再包含子包,如一个文件夹中可以包含子文件夹一样。
**类名永远是和文件名对应的,类名是Hello,对应的文件就是Hello.java** **类名永远是和文件名对应的,类名是Hello,对应的文件就是Hello.java**
@@ -452,7 +452,7 @@ public class Hello {
} }
``` ```
注意,第一行并没有 package 这个明。在看看文件系统: 注意,第一行并没有 package 这个明。在看看文件系统:
![](img/20230302100109.png) ![](img/20230302100109.png)
@@ -460,7 +460,7 @@ Hello.java 这个文件的确在src文件夹中。
**src文件夹中的类文件的package可以不用写,代表在缺省包中,也就是src这个文件夹中。** **src文件夹中的类文件的package可以不用写,代表在缺省包中,也就是src这个文件夹中。**
**如果需要改变源文件的位置,请在Eclipse中的项目管理中进行(支持文件的复制、移动、删除等操作)。Eclipse始终会保持源代码中的package明的正确性。这个功能其实在高级的IDE中叫做重构(Refactor),重构还有很多应用,例如批量修改函数名、变量名等功能,可以在菜单 Refactor 中找到更多的功能。** **如果需要改变源文件的位置,请在Eclipse中的项目管理中进行(支持文件的复制、移动、删除等操作)。Eclipse始终会保持源代码中的package明的正确性。这个功能其实在高级的IDE中叫做重构(Refactor),重构还有很多应用,例如批量修改函数名、变量名等功能,可以在菜单 Refactor 中找到更多的功能。**
### 4.3. Java代码结构 ### 4.3. Java代码结构
@@ -481,7 +481,7 @@ public class Hello {
} }
``` ```
1. package:包描述,该源代码在那个包,对应src文件夹中的文件夹。如果有多个层级的包(src子文件夹中的子文件夹),使用点(.)来分割包名。尝试一下在包下面建立子包后package是如何描述的。package不是必须的,如果java文件在src中,package可以省略,这时表示缺省包。 1. package:包描述,该源代码在那个包,对应src文件夹中的文件夹。如果有多个层级的包(src子文件夹中的子文件夹),使用点(.)来分割包名。尝试一下在包下面建立子包后package是如何描述的。package不是必须的,如果Java文件在src中,package可以省略,这时表示缺省包。
2. 一般来说,一个Java文件包含一个类(Class)结构,如果有多个并列的Class结构,只能有一个描述成public。关于public的含义后面会讲到。 2. 一般来说,一个Java文件包含一个类(Class)结构,如果有多个并列的Class结构,只能有一个描述成public。关于public的含义后面会讲到。
3. 类名(或者描述成public的类名),这个例子是Hello,必须和主文件名一致。 3. 类名(或者描述成public的类名),这个例子是Hello,必须和主文件名一致。
4. Java中的变量、常量、函数等结构都属于一个类(Class),在类外面定义非类(Class)的结构都是非法的。 4. Java中的变量、常量、函数等结构都属于一个类(Class),在类外面定义非类(Class)的结构都是非法的。
@@ -628,7 +628,7 @@ eclipse的调试界面是单独的布局,第一次运行调试会提示进入
### 6.2. 代码格式化 ### 6.2. 代码格式化
菜单 Souorce->Format 或者快捷键 Ctl+Shift+F ,可以使当前代码快速美化。漂亮的代码缩进和编码规则会让代码更容易阅读。 菜单 Source->Format 或者快捷键 Ctrl+Shift+F ,可以使当前代码快速美化。漂亮的代码缩进和编码规则会让代码更容易阅读。
**不同系统下 Eclipse 的快捷键可能并不相同,注意参考你自己Eclipse的快捷键。** **不同系统下 Eclipse 的快捷键可能并不相同,注意参考你自己Eclipse的快捷键。**
+6 -5
View File
@@ -28,7 +28,7 @@ public class ComputeArea {
} }
``` ```
2-10行的语法结构和C完全一致,这里我门只关心13行的代码。从第13行代码看出什么?首先是 System.out.pringln 这显然是一个函数,表示要打印一个字符串。 2-10行的语法结构和C完全一致,这里我门只关心13行的代码。从第13行代码看出什么?首先是 System.out.println 这显然是一个函数,表示要打印一个字符串。
**按住ctl键盘,然后鼠标左键点击第13行的println,Eclipse会打开一个新的文件(PrintStream.class),并定位到println这个函数的位置。Eclipse这种特性叫做代码跳转,可以方便的浏览代码。** **按住ctl键盘,然后鼠标左键点击第13行的println,Eclipse会打开一个新的文件(PrintStream.class),并定位到println这个函数的位置。Eclipse这种特性叫做代码跳转,可以方便的浏览代码。**
@@ -51,7 +51,7 @@ public class ComputeArea {
再总结一下我们学的的: 再总结一下我们学的的:
1. main函数的固定写法; 1. main函数的固定写法;
2. main函数必须在一public类中定义; 2. main函数必须在一public类中定义;
3. 字符串的表示和连接; 3. 字符串的表示和连接;
4. 如何使用打印函数。 4. 如何使用打印函数。
@@ -99,11 +99,11 @@ public class ComputeAreaWithConsoleInput {
因此第6行的Scanner是一个类,使用 new 关键字生成一个对象并把引用地址(指针)赋值给 input 这个变量。 因此第6行的Scanner是一个类,使用 new 关键字生成一个对象并把引用地址(指针)赋值给 input 这个变量。
**注意:Scanner即是一个类型,也是一个函数;不过这个函数必须和 new 关键字配合使用,这个函数叫做构造函数,当一个类实例化的时候用作进行一些初始化操作;构造函数是可以带参数的;例如这里的System.in。关于构造函数,后面有专门的内容进行讨论,这里需要进行初步的了解。** **注意:Scanner即是一个类型,也是一个函数;不过这个函数必须和 new 关键字配合使用,这个函数叫做构造函数,当一个类实例化的时候用作进行一些初始化操作;构造函数是可以带参数的;例如这里的System.in。关于构造函数,后面有专门的内容进行讨论,这里需要进行初步的了解。**
为Scanner类的构造函数传递一个叫做 System.in 的参数,表示Scanner从系统标准输入(一般是键盘)中读取数据。类似C的输入/输出重定向一样,Java也可以从文件读取数据,这个以后再讲。 为Scanner类的构造函数传递一个叫做 System.in 的参数,表示Scanner从系统标准输入(一般是键盘)中读取数据。类似C的输入/输出重定向一样,Java也可以从文件读取数据,这个以后再讲。
当生成类型为Scanner的对象input后,就可以直接在input上使用相应的函数读取不同类型的数据了。例如netDouble()函数是从键盘读取一个double类型的值,直到遇到空格或者是回车(空格并不能使nextDouble函数返回,只有回车可以让nextDouble函数返回)。程序在运行到nextDouble这个函数的时候,会等待,直到输入回车后把值读取到radius变量。 当生成类型为Scanner的对象input后,就可以直接在input上使用相应的函数读取不同类型的数据了。例如nextDouble()函数是从键盘读取一个double类型的值,直到遇到空格或者是回车(空格并不能使nextDouble函数返回,只有回车可以让nextDouble函数返回)。程序在运行到nextDouble这个函数的时候,会等待,直到输入回车后把值读取到radius变量。
其他代码比较简单,就不解释了。 其他代码比较简单,就不解释了。
@@ -221,4 +221,5 @@ float e = 33.3F;
3. 如何读取键盘输入,以及赋值。注意不同的类型使用不同的函数; 3. 如何读取键盘输入,以及赋值。注意不同的类型使用不同的函数;
4. 如何判断是否还有没有读取的数据(hasNext函数XXX); 4. 如何判断是否还有没有读取的数据(hasNext函数XXX);
5. 基本数据类型:全部都是小写,以后会学习对应大写的包装类型;都是有符号的; 5. 基本数据类型:全部都是小写,以后会学习对应大写的包装类型;都是有符号的;
6. 如何声明常量(final);7. 类型转换以及规则。 6. 如何声明常量(final);
7. 类型转换以及规则。
+2 -2
View File
@@ -4,7 +4,7 @@
Java的布尔类型和C保持一致,基本的运算符也和C保持一致。 Java的布尔类型和C保持一致,基本的运算符也和C保持一致。
**注意,布尔类型是 boolean有大写的布尔类型Boolean。这两个类型是不同的,小写的是基本类型(与C一致);大写的表示封装类型(类)是面向对象的类型。** **注意,布尔类型是 boolean有大写的布尔类型Boolean。这两个类型是不同的,小写的是基本类型(与C一致);大写的表示封装类型(类)是面向对象的类型。**
### 1.1. 关系运算 ### 1.1. 关系运算
@@ -90,7 +90,7 @@ public class LoopRead {
## 2. 重点 ## 2. 重点
本章的内容中的大部分技术要点都与C保持一致,因此需要掌握几个例子就可以了: 本章的内容中的大部分技术要点都与C保持一致,因此需要掌握几个例子就可以了:
1. 以下几个例子都比较简单,需要掌握: 1. 以下几个例子都比较简单,需要掌握:
1. AdditionQuiz 1. AdditionQuiz
+2 -2
View File
@@ -10,7 +10,7 @@
2. 常量 2. 常量
3. 函数 3. 函数
这一章暂时不设计基数据结构,数据结构在另外的章节专门讲解。这里的重点是: 这一章暂时不涉及基础数据结构,数据结构在另外的章节专门讲解。这里的重点是:
1. 常量 PI 1. 常量 PI
2. 取整函数 2. 取整函数
@@ -245,7 +245,7 @@ public class Main {
} }
``` ```
这里 Interger 或者是 Float 是一个类,而非对象。我们把在类上面可以直接调用的方法(不需要实例化成对象),叫做静态方法。关于静态方法,后面学到类的时候还会讲解。 这里 Integer 或者是 Float 是一个类,而非对象。我们把在类上面可以直接调用的方法(不需要实例化成对象),叫做静态方法。关于静态方法,后面学到类的时候还会讲解。
**parseXXX 方法和 valueOf 方法都可以返回相应字符串对应的数值类型(看你是在哪个类型上调用的),区别是 valueOf 返回的是包装类型,parseXXX返回的是基本类型。** **parseXXX 方法和 valueOf 方法都可以返回相应字符串对应的数值类型(看你是在哪个类型上调用的),区别是 valueOf 返回的是包装类型,parseXXX返回的是基本类型。**
+4 -4
View File
@@ -13,7 +13,7 @@ Java的函数和 C 类似,但因为Java是面向对象的语言,所以又有
空函数在语法上将是存在的,例如下面一个Java的空函数: 空函数在语法上将是存在的,例如下面一个Java的空函数:
```java ```java
void nullFunxtion(){ void nullFunction(){
// 没有算法,不返回,没有任何功能 // 没有算法,不返回,没有任何功能
} }
``` ```
@@ -43,7 +43,7 @@ public class Test {
} }
``` ```
上面的函数 `static void add(int i)` 这个函数就是没有返回值的,但是函数中的算法有效果:对变量sum进行累加。当然,其他的一些没有返回值的函数可能产其他的效果:例如打印、文件输出、网络连接... 这些都是函数产生的影响,也是函数存在的意义。 上面的函数 `static void add(int i)` 这个函数就是没有返回值的,但是函数中的算法有效果:对变量sum进行累加。当然,其他的一些没有返回值的函数可能产其他的效果:例如打印、文件输出、网络连接... 这些都是函数产生的影响,也是函数存在的意义。
### 1.3. 有返回值的函数 ### 1.3. 有返回值的函数
@@ -190,7 +190,7 @@ public class Test {
## 3. 函数签名与函数重载 ## 3. 函数签名与函数重载
java中,一个函数能看起来很复杂,不仅有返回值,还有前面的public和static等修饰(这些修饰是可选的)。函数签名的概念是一个函数的函数名连同其形式参数列表叫做函数签名。 Java中,一个函数能看起来很复杂,不仅有返回值,还有前面的public和static等修饰(这些修饰是可选的)。函数签名的概念是一个函数的函数名连同其形式参数列表叫做函数签名。
在一个类中,可能出现两个同名的函数,只要他们的参数列表不同就可以,这种方式叫做函数重载,对比C语言,是没有函数重载的。函数重载避免了C语言中,因为功能相似,而参数名不同需要用多个不同的函数名的问题。大家可以看到C语言的函数名大多很长,其实是因为C的所有函数都是全局存储的(Java是把函数放在盒子Class里,不同的Class中可以存在同名且同参数的函数),另外就是C没有函数重载的机制。 在一个类中,可能出现两个同名的函数,只要他们的参数列表不同就可以,这种方式叫做函数重载,对比C语言,是没有函数重载的。函数重载避免了C语言中,因为功能相似,而参数名不同需要用多个不同的函数名的问题。大家可以看到C语言的函数名大多很长,其实是因为C的所有函数都是全局存储的(Java是把函数放在盒子Class里,不同的Class中可以存在同名且同参数的函数),另外就是C没有函数重载的机制。
@@ -268,7 +268,7 @@ public class Test {
> You can declare a local variable with the same name multiple times in different non-nesting blocks in a method, but you cannot declare a local variable twice in nested blocks. > You can declare a local variable with the same name multiple times in different non-nesting blocks in a method, but you cannot declare a local variable twice in nested blocks.
上面说明了什么叫做局部变量(就是函数中的变量,这个和C的定义是一致的),以及局部变量的访问范围(作用域)。一句话,局部变量的作用域在其定义的时候开始,一到该语法块结束。 上面说明了什么叫做局部变量(就是函数中的变量,这个和C的定义是一致的),以及局部变量的访问范围(作用域)。一句话,局部变量的作用域在其定义的时候开始,一到该语法块结束。
```java ```java
public class Test { public class Test {
+6 -6
View File
@@ -26,7 +26,7 @@ public class ArrayTest {
} }
``` ```
Java中数组的声明与使用与C类似,`int[] myList` 定义了一个可以存放int数据类型的数组,但是此时还没有为这个数组分配内存。这一点和C的指针类,其实myList这个变量叫做引用变量,也和指针类似。 Java中数组的声明与使用与C类似,`int[] myList` 定义了一个可以存放int数据类型的数组,但是此时还没有为这个数组分配内存。这一点和C的指针类,其实myList这个变量叫做引用变量,也和指针类似。
要为myList这个数组分配内存,使用 `new int[2]` 这种类似的语法。该语法返回一个数组对象的引用地址,数组的容量是2,并赋值给引用变量 myList,然后就可以通过引用变量 myList对数组进行操作了。 要为myList这个数组分配内存,使用 `new int[2]` 这种类似的语法。该语法返回一个数组对象的引用地址,数组的容量是2,并赋值给引用变量 myList,然后就可以通过引用变量 myList对数组进行操作了。
@@ -250,7 +250,7 @@ public class Test {
} }
``` ```
排序后,数组中的元素按照从小到排列。 排序后,数组中的元素按照从小到排列。
### 2.8. 数组元素的查找 ### 2.8. 数组元素的查找
@@ -269,7 +269,7 @@ public class Test {
} }
``` ```
这个函数就是binarySearch这个函数指使用注意这个函数的使用,前面的一`java.util.Arrays` 不是都指类的名字;最有最后的 `Arrays` 是类名,而 `java.util` 是命名空间。通常情况下,可以简单的理解命名空间就是目录的层级关系。 这个函数就是binarySearch,注意这个函数的使用,前面的一`java.util.Arrays` 不是都指类的名字;最有最后的 `Arrays` 是类名,而 `java.util` 是命名空间。通常情况下,可以简单的理解命名空间就是目录的层级关系。
关于`java.util.Arrays`这个类还有很多其他函数,可以在IDE中通过输入点(.)查看: 关于`java.util.Arrays`这个类还有很多其他函数,可以在IDE中通过输入点(.)查看:
@@ -334,11 +334,11 @@ public class Calculator {
} }
``` ```
主函数`void main(String[] args)` 中有有一个args 的字符串数组。编译这个程序,然后在命令行下执行,如果不记得命令行中如何编译和运行java,请参考第一章中的内容。 主函数`void main(String[] args)` 中有有一个args 的字符串数组。编译这个程序,然后在命令行下执行,如果不记得命令行中如何编译和运行Java,请参考第一章中的内容。
![](img/2023-03-04-15-41-18-image.png) ![](img/2023-03-04-15-41-18-image.png)
在命令行中运行编译好的代码 `java Calculator 1 + 21` 其中 java是指虚拟机,后面的 `Calculator` 是Java编译后的可执行代码;`1 + 21` 是命令行参数。这个参数会传递给Calculator的主程序,通过main函数的args这个字符串数组解析出来。如同Scanner 对象一样,解析这个数组是按照空格区分的,因此,这个例子中我们得到的args数组是: 在命令行中运行编译好的代码 `java Calculator 1 + 21` 其中java是运行Java程序的命令,后面的 `Calculator` 是Java编译后的可执行代码;`1 + 21` 是命令行参数。这个参数会传递给Calculator的主程序,通过main函数的args这个字符串数组解析出来。如同Scanner 对象一样,解析这个数组是按照空格区分的,因此,这个例子中我们得到的args数组是:
| 数组元素 | 值 | 说明 | | 数组元素 | 值 | 说明 |
| ------- | --- | --- | | ------- | --- | --- |
@@ -351,7 +351,7 @@ public class Calculator {
     
## 4. 本章重点 ## 4. 本章重点
1. 掌握数组的明和使用; 1. 掌握数组的明和使用;
2. 掌握增强for循环的使用; 2. 掌握增强for循环的使用;
3. 理解数组作为函数参数的使用; 3. 理解数组作为函数参数的使用;
4. 其他内容均为了解。 4. 其他内容均为了解。
+8 -8
View File
@@ -11,7 +11,7 @@
好了,这就是类与对象的基本内涵。类是一个模板(抽象的描述),对象是模板的一个实例(具体的)。这一点有点类似C中结构体的定义与结构体变量的关系,定义是抽象描述,变量是实体。 好了,这就是类与对象的基本内涵。类是一个模板(抽象的描述),对象是模板的一个实例(具体的)。这一点有点类似C中结构体的定义与结构体变量的关系,定义是抽象描述,变量是实体。
我们再深入讨论一下对象。对象(Object)这个概念广泛存在于我们的生活当中,一般一个独立的个体,具备一定的特性(properties),并有一定的能力(capability)。例如,一辆A100 我们再深入讨论一下对象。对象(Object)这个概念广泛存在于我们的生活当中,一般一个独立的个体,具备一定的特性(properties),并有一定的能力(capability)。例如,一辆A100
![Alt text](img/A100.drawio.svg) ![Alt text](img/A100.drawio.svg)
@@ -23,7 +23,7 @@
考虑到已经学习过C语言,使用C语言中的结构体来帮助理解抽象描述与实例的关系。 考虑到已经学习过C语言,使用C语言中的结构体来帮助理解抽象描述与实例的关系。
这个例子是描述平面中的一个圆。这里我们需要两组参数来描述圆,第一个参数是坐标位置(X、Y);另外一个是圆本的描述,例如大小(半径r),可能还有颜色等等,简单来说,我们目前只有半径。如果从C语言出发,需要建立一个结构体来描述圆,请同学们写出该结构体的代码。 这个例子是描述平面中的一个圆。这里我们需要两组参数来描述圆,第一个参数是坐标位置(X、Y);另外一个是圆本的描述,例如大小(半径r),可能还有颜色等等,简单来说,我们目前只有半径。如果从C语言出发,需要建立一个结构体来描述圆,请同学们写出该结构体的代码。
如果从C语言出发,需要建立一个结构体来描述圆,代码如下: 如果从C语言出发,需要建立一个结构体来描述圆,代码如下:
@@ -135,7 +135,7 @@ public class Circle_Test {
} }
``` ```
**注意`setCircle`函数中的`this.x = x`这样的写法。因为这个对象本有变量x、y、z;这些变量叫做成员变量,其作用域是在整个类的定义范围内;但是`setCircle`的形式参数中的x、y、z与成员变量重名了,但是语义不同。为了区分这两个变量,使用this关键字,`this.x`代表对象的成员变量,而`x`代表传递进来的参数。** **注意`setCircle`函数中的`this.x = x`这样的写法。因为这个对象本有变量x、y、z;这些变量叫做成员变量,其作用域是在整个类的定义范围内;但是`setCircle`的形式参数中的x、y、z与成员变量重名了,但是语义不同。为了区分这两个变量,使用this关键字,`this.x`代表对象的成员变量,而`x`代表传递进来的参数。**
### 1.5. 构造函数 ### 1.5. 构造函数
@@ -251,7 +251,7 @@ SDK中的一些类:
## 4. 类的成员 ## 4. 类的成员
在本章节以前,我们也看到过类,也有相应的变量和函数,但是大多是静态的。本章开始,如同Circle类一样,定义的变量、函数都没有static的修饰,叫做实体变量和实体函数(区别于态)。实体类型的变量和函数只能在引用对象的变量上面进行调用,而不能在类上进行调用。 在本章节以前,我们也看到过类,也有相应的变量和函数,但是大多是静态的。本章开始,如同Circle类一样,定义的变量、函数都没有static的修饰,叫做实体变量和实体函数(区别于态)。实体类型的变量和函数只能在引用对象的变量上面进行调用,而不能在类上进行调用。
定义在类中的变量、常量、函数都叫做类的成员,根据这些成员的不同性质,总结一下: 定义在类中的变量、常量、函数都叫做类的成员,根据这些成员的不同性质,总结一下:
@@ -326,7 +326,7 @@ public class Test {
``` ```
1. 静态变量`numberOfObjects`的初始值是0,因此在主函数的第二行,使用`CircleWithStaticMembers.getNumberOfObjects()`取得这个静态变量的值的时候是0。这里证明了静态变量不依附对象存在,可以在类上面直接调用。 1. 静态变量`numberOfObjects`的初始值是0,因此在主函数的第二行,使用`CircleWithStaticMembers.getNumberOfObjects()`取得这个静态变量的值的时候是0。这里证明了静态变量不依附对象存在,可以在类上面直接调用。
2. `CircleWithStaticMembers`的两个构造函数(重载的构造函数)都对`numberOfObjects`进行了加1操作,语义是当创建一个`CircleWithStaticMembers`对象的时候,让静态变量`numberOfObjects`加1,这样就得到了创建`CircleWithStaticMembers`对象的总数量。 2. `CircleWithStaticMembers`的两个构造函数(重载的构造函数)都对`numberOfObjects进行了加1操作,语义是当创建一个`CircleWithStaticMembers`对象的时候,让静态变量`numberOfObjects`加1,这样就得到了创建`CircleWithStaticMembers`对象的总数量。
3. 注意后面的代码,得到`CircleWithStaticMembers`类实例化对象的个数可以使用静态变量`numberOfObjects`,也可以使用静态函数`getNumberOfObjects()。`且这两个静态成员即可以在类上面调用,也可以在对象的引用变量上调用。 3. 注意后面的代码,得到`CircleWithStaticMembers`类实例化对象的个数可以使用静态变量`numberOfObjects`,也可以使用静态函数`getNumberOfObjects()。`且这两个静态成员即可以在类上面调用,也可以在对象的引用变量上调用。
**静态成员可以在类上访问,也可以在该类的引用变量上访问;这两种方式都是合法的,且没有任何的区别。** **静态成员可以在类上访问,也可以在该类的引用变量上访问;这两种方式都是合法的,且没有任何的区别。**
@@ -408,7 +408,7 @@ public class CircleWithPrivateDataFields {
} }
``` ```
这样清楚了,`radius` 这个变量被设置成私有,`getRadius()` 是共有函数,用于读取半径;`setRadius()` 是共有函数,用于设置半径。这两个函数就是 getter 和 setter 函数。特别注意,在 `setRadius` 函数中对传入参数进行了判断。这个函数好像是看门人,保证半径永远不为数。 这样清楚了,`radius` 这个变量被设置成私有,`getRadius()` 是共有函数,用于读取半径;`setRadius()` 是共有函数,用于设置半径。这两个函数就是 getter 和 setter 函数。特别注意,在 `setRadius` 函数中对传入参数进行了判断。这个函数好像是看门人,保证半径永远不为数。
因为getter和setter函数用得太多了,eclipse 和大多Java的IDE为这个函数提供了快速构建方式。你只需要选择菜单`Source`-`Generate Getters and Setters ...`就会出现下面的窗口。 因为getter和setter函数用得太多了,eclipse 和大多Java的IDE为这个函数提供了快速构建方式。你只需要选择菜单`Source`-`Generate Getters and Setters ...`就会出现下面的窗口。
@@ -493,7 +493,7 @@ public class TestPassObject {
这个例子证明,如果是引用变量,在函数内部可以改变传入对象的成员变量值;其实这里使用的是setter函数改变半径的,因为半径是私有的;如果半径是public的,使用直接赋值也可以改变。 这个例子证明,如果是引用变量,在函数内部可以改变传入对象的成员变量值;其实这里使用的是setter函数改变半径的,因为半径是私有的;如果半径是public的,使用直接赋值也可以改变。
如果我`printAreas`函数执行完成后,打印n这个变量(作为参数times传入`printAreas`函数),会发现这个值还是5;因为基本类型的变量使用的是值传递。 如果我`printAreas`函数执行完成后,打印n这个变量(作为参数times传入`printAreas`函数),会发现这个值还是5;因为基本类型的变量使用的是值传递。
## 7. 对象数组 ## 7. 对象数组
@@ -590,7 +590,7 @@ public class TotalArea {
If the contents of an object cannot be changed once the object is created, the object is called an immutable(不变的) object and its class is called an immutable class. If you delete the set method in the Circle class in Listing 8.10, the class would be immutable because radius is private and cannot be changed without a set method. If the contents of an object cannot be changed once the object is created, the object is called an immutable(不变的) object and its class is called an immutable class. If you delete the set method in the Circle class in Listing 8.10, the class would be immutable because radius is private and cannot be changed without a set method.
这个概念需要了解,我们目前使用到的Immutable类是Spring,下一章中所有的 warp 类型也是 Immutable。 这个概念需要了解,我们目前使用到的Immutable类是String,下一章中所有的 wrapper 类型也是 Immutable。
## 9. 变量作用域 ## 9. 变量作用域
+2 -2
View File
@@ -22,7 +22,7 @@
## 2. 封装类型 Wrapper class ## 2. 封装类型 Wrapper class
回忆一下前面我们学到的基本类型(primitive 类型),这些类型包括所有的以小写字母头的Java预定义类型。 回忆一下前面我们学到的基本类型(primitive 类型),这些类型包括所有的以小写字母头的Java预定义类型。
1. byte 1. byte
2. short 2. short
@@ -87,7 +87,7 @@ Character类的`Character.isDigit(char)``Character.isLetter(char)`这些函
Byte b = 10; // 这是合法的 Byte b = 10; // 这是合法的
Short s = 100; Short s = 100;
Integer i = 200; Integer i = 200;
Long l = 999999L; // 字面量缺省是int类型,需要标记成L(长整型) Long l = 999999L; // 字面量缺省是int类型,需要标记成L(长整型)
Float f = 3.14F; // 字面量是double类型,需要标记成F(浮点类型) Float f = 3.14F; // 字面量是double类型,需要标记成F(浮点类型)
Double d = 33.33; Double d = 33.33;
``` ```
+13 -13
View File
@@ -8,7 +8,7 @@
在C语言中,降低代码冗余(增加代码复用性),一般使用函数来实现;但是函数是一个高纬度的抽象,和我们日常生活联系并不紧密。那么我们考虑日常生活中的例子。 在C语言中,降低代码冗余(增加代码复用性),一般使用函数来实现;但是函数是一个高纬度的抽象,和我们日常生活联系并不紧密。那么我们考虑日常生活中的例子。
通常我们描述一猫,只用说明猫是:界:动物界;门:脊椎动亚门;纲:哺乳纲;目:食肉目;科:猫科;属:猫属;种:猫种。 通常我们描述一猫,只用说明猫是:界:动物界;门:脊椎动亚门;纲:哺乳纲;目:食肉目;科:猫科;属:猫属;种:猫种。
![Alt text](img/%E7%94%9F%E7%89%A9%E5%88%86%E7%B1%BB.drawio.svg) ![Alt text](img/%E7%94%9F%E7%89%A9%E5%88%86%E7%B1%BB.drawio.svg)
上述的图表示物种分类的一部分。这样描述一个物种的分类有很多好处: 上述的图表示物种分类的一部分。这样描述一个物种的分类有很多好处:
@@ -17,13 +17,13 @@
2. 后代具备祖先的所有特性; 2. 后代具备祖先的所有特性;
3. 明确不同种之间的关系。 3. 明确不同种之间的关系。
如果大家都清楚上述的规则,当我们讨论猫种的时候,就默认猫种具备祖先的所有特性,而不必再说明猫种是脊椎动物,胎生等这些它祖先所具备的特性。这种特性在Java的类也存在,这就是继承。 如果大家都清楚上述的规则,当我们讨论猫种的时候,就默认猫种具备祖先的所有特性,而不必再说明猫种是脊椎动物,胎生等这些它祖先所具备的特性。这种特性在Java的类也存在,这就是继承。
### 1.2. Java中的继承(411) ### 1.2. Java中的继承(411)
例如要在平面上描述两个类,圆和矩形,那么这两个类好像有一些基本的特性是一致的。例如,填充颜色color,是否填充 filled,对象创建时间 dateCreated等。另外,需要对上述属性设置或者读取的方法:getColor()setColor()isFilled()setFilled()等。 例如要在平面上描述两个类,圆和矩形,那么这两个类好像有一些基本的特性是一致的。例如,填充颜色color,是否填充 filled,对象创建时间 dateCreated等。另外,需要对上述属性设置或者读取的方法:getColor()setColor()isFilled()setFilled()等。
如果每个类都需要描述所有的这些特性好像有点浪费,如何做到降低代码冗余?我们使用到继承,如下图表述,GeometrocObject是父类,包括所有子类共有的特性(数据和方法);Circle和Rectangle继承于GeometrocObject。这样在编写Circle和Rectangle的时候就只需要对其特性进行描述就可以了;这两个类的共性在其父类中以及体现出来了,子类完全继承父类的所有特性(数据和方法)。 如果每个类都需要描述所有的这些特性好像有点浪费,如何做到降低代码冗余?我们使用到继承,如下图表述,GeometricObject是父类,包括所有子类共有的特性(数据和方法);Circle和Rectangle继承于GeometrocObject。这样在编写Circle和Rectangle的时候就只需要对其特性进行描述就可以了;这两个类的共性在其父类中以及体现出来了,子类完全继承父类的所有特性(数据和方法)。
![image-20230311122706219](img/image-20230311122706219.png) ![image-20230311122706219](img/image-20230311122706219.png)
@@ -148,7 +148,7 @@ public class CircleFromSimpleGeometricObject extends SimpleGeometricObject {
} }
``` ```
1. 子类Circle使用`extend SimpleGeometricObject`表明继承于`SimpleGeometricObject`那么子类拥有父类的所有特性(数据和方法); 1. 子类Circle使用`extends SimpleGeometricObject`表明继承于`SimpleGeometricObject`那么子类拥有父类的所有特性(数据和方法);
2. 但是请注意,虽然子类拥有父类的所有特性,不意味子类就可以无限制的访问这些特性,例如`color``filled``dateCreated` 这些是父类的私有变量,在子类中并不能访问,而要通过对应的getter和setter函数访问(这些函数是公开的); 2. 但是请注意,虽然子类拥有父类的所有特性,不意味子类就可以无限制的访问这些特性,例如`color``filled``dateCreated` 这些是父类的私有变量,在子类中并不能访问,而要通过对应的getter和setter函数访问(这些函数是公开的);
3. `CircleFromSimpleGeometricObject`增加了自己的特性`radius`并设置成私有,以及对应的getter和setter函数; 3. `CircleFromSimpleGeometricObject`增加了自己的特性`radius`并设置成私有,以及对应的getter和setter函数;
4. 子类中增加了自己的行为:`getArea()``getPerimeter``printCircle()` 4. 子类中增加了自己的行为:`getArea()``getPerimeter``printCircle()`
@@ -275,7 +275,7 @@ class Man extends Person {
} }
``` ```
例子中定义的 Man 类将出现编译错误,因为 Person 缺少不带参数的构造函数,Person 又没有显式的调用Person带参数的构造函数。修改 Man 类如下就可以了: 例子中定义的 Man 类将出现编译错误,因为 Person 缺少不带参数的构造函数,Person 又没有显式的调用Person带参数的构造函数。修改 Man 类如下就可以了:
```java ```java
class Man extends Person { class Man extends Person {
@@ -328,7 +328,7 @@ class Person {
} }
``` ```
main函数起来比较奇怪,为什么在Faculty内中,又使用new 方法构造自己所在的类?其实大家不用太关心main函数在那里。首先因为java虚拟机要访问到这个静态函数作为程序的入口;其次,对于 main 函数,只要被构建的类对于main函数来说是可以访问就行了。上述所有类型都定义在一个文件当中,这样如同是一个包;因此main函数可以访问该文件中的所有类;进而,也可以访问 Faculty 类,构建 Faculty 类的对象当然也是可以的。其实把main函数放在这个文件的任何类中都是可以的,只不过我们习惯放在 Faculty 这个类中(这个文档的文件名也是和这个类一致的)。 main函数起来比较奇怪,为什么在Faculty内中,又使用new 方法构造自己所在的类?其实大家不用太关心main函数在那里。首先因为Java虚拟机要访问到这个静态函数作为程序的入口;其次,对于 main 函数,只要被构建的类对于main函数来说是可以访问就行了。上述所有类型都定义在一个文件当中,这样如同是一个包;因此main函数可以访问该文件中的所有类;进而,也可以访问 Faculty 类,构建 Faculty 类的对象当然也是可以的。其实把main函数放在这个文件的任何类中都是可以的,只不过我们习惯放在 Faculty 这个类中(这个文档的文件名也是和这个类一致的)。
@@ -394,7 +394,7 @@ public class Test {
} }
``` ```
Apple中没有toString()函数,但是其父类型后,因此Apple也得到了这样的能力。其实是间接调用父类型的toString()函数。 Apple中没有toString()函数,但是继承其父类型后,因此Apple也得到了这样的能力。其实是间接调用父类型的toString()函数。
### 3.2. 覆盖父类型的函数 ### 3.2. 覆盖父类型的函数
@@ -461,7 +461,7 @@ This is an apple.
This is fruit. This is fruit.
``` ```
1、2行输出是`System.out.println(apple.toString());` 的结果。可以看到第1行是Apple类中`toString()`函数使用`super.toString()`调用了Fruit类中`toString`的结果。第3行使用Apple的函数`printFruitToString()`,本质也是使用了`super.toString()` 1、2行输出是`System.out.println(apple.toString());` 的结果。可以看到第1行是Apple类中`toString()`函数使用`super.toString()`调用了Fruit类中`toString`的结果。第3行使用Apple的函数`printFruitToString()`,本质也是使用了`super.toString()`
**注意:super关键字只能在直接子类中使用,表示其直接父类。** **注意:super关键字只能在直接子类中使用,表示其直接父类。**
@@ -671,7 +671,7 @@ java.lang.Object@7e774085
上面文字使用下面的例子来解释:Apple这个例子中,我们再次扩展Apple,为一个GiantApple类: 上面文字使用下面的例子来解释:Apple这个例子中,我们再次扩展Apple,为一个GiantApple类:
```java ```java
sclass GiantApple extends Apple { class GiantApple extends Apple {
} }
@@ -745,7 +745,7 @@ Orange orange = fruit; // 非法
1. 真实对象是Fruit 1. 真实对象是Fruit
2. 引用变量类型是 Orange 2. 引用变量类型是 Orange
3. Orange是Fruit的子类型,其能力大于(准确的说是不小于)Fruit; 3. Orange是Fruit的子类型,其能力大于(准确的说是不小于)Fruit;
4. 用较大的能力声明去定义一个较小能力的对象,而对其进行调用,可能造成能力不匹配的问题。例如,Orange 有一个`printInfo()`的方法,而Fruit没有,当用 `orange.pringInfo()`进行调用的时候,因为真实对象不具备这个能力,所以导致出错。 4. 用较大的能力声明去定义一个较小能力的对象,而对其进行调用,可能造成能力不匹配的问题。例如,Orange 有一个`printInfo()`的方法,而Fruit没有,当用 `orange.printInfo()`进行调用的时候,因为真实对象不具备这个能力,所以导致出错。
因此:父类型赋值给子类型是非法的!其隐含的语义是 Fruit 是 Orange,这显然是不正确的。 因此:父类型赋值给子类型是非法的!其隐含的语义是 Fruit 是 Orange,这显然是不正确的。
@@ -908,15 +908,15 @@ public class TestArrayList {
} }
``` ```
掌握书上这个例子应该是足够了。注意ArrayList的声明方式,这是泛型明。关于泛型,我们只需要知道如何使用就可以了,不用关心太多。 掌握书上这个例子应该是足够了。注意ArrayList的声明方式,这是泛型明。关于泛型,我们只需要知道如何使用就可以了,不用关心太多。
```java ```java
ArrayList<String> cityList = new ArrayList(); ArrayList<String> cityList = new ArrayList();
``` ```
尖括号中的就是泛型,表达的语义是ArrayList中转载的数据是什么类型。当然,如果是`ArrayList<Object>`那么可以装任何的引用类型。 尖括号中的就是泛型,表达的语义是ArrayList中存放的数据是什么类型。当然,如果是`ArrayList<Object>`那么可以装任何的引用类型。
**注意:泛型中尖括号的类型必须是引用类型,不能是原始类型。** **注意:泛型中尖括号的类型必须是引用类型,不能是原始类型。**
需要了解ArrayList和Array间的相互转换: 需要了解ArrayList和Array间的相互转换:
+6 -6
View File
@@ -122,7 +122,7 @@ public class Circle extends GeometricObject {
```java ```java
public class Rectangle extends GeometricObject { public class Rectangle extends GeometricObject {
private double width; private double width;
private Double height; private double height;
public Rectangle() { public Rectangle() {
} }
@@ -164,7 +164,7 @@ public class Rectangle extends GeometricObject {
} }
``` ```
上述两个类都实现(impliment)了(覆盖了)`getArea()``getPerimeter()`两个函数(这两个函数都有函数体),且这两个类都没有使用 abstract 进行修饰,那么这两个类是可以被实例化的。 上述两个类都实现(implement)了(覆盖了)`getArea()``getPerimeter()`两个函数(这两个函数都有函数体),且这两个类都没有使用 abstract 进行修饰,那么这两个类是可以被实例化的。
看看主函数如何使用多态调用的: 看看主函数如何使用多态调用的:
@@ -209,7 +209,7 @@ public class TestGeometricObject {
1. 实例化我没有任何实际的意义; 1. 实例化我没有任何实际的意义;
2. 我只是描述我后代必须具备的能力; 2. 我只是描述我后代必须具备的能力;
3. 后代的某些能力我知道是什么(函数原型),但是我不知道如何实现(算法),因为他们变化太多了;这些能力我就只描述成抽象的方法(只有函数明,没有函数体)。 3. 后代的某些能力我知道是什么(函数原型),但是我不知道如何实现(算法),因为他们变化太多了;这些能力我就只描述成抽象的方法(只有函数明,没有函数体)。
4. 有些能力我知道如何实现,这些能力就是非抽象的方法。 4. 有些能力我知道如何实现,这些能力就是非抽象的方法。
**抽象类不能实例化,但是作为参数,用作多态实现通用编程非常有用!** **抽象类不能实例化,但是作为参数,用作多态实现通用编程非常有用!**
@@ -393,7 +393,7 @@ public interface Edible {
> An interface is treated like a special class in Java. Each interface is compiled into a separate bytecode file, just like a regular class. Like an abstract class, you cannot create an instance from an interface using the new operator, but in most cases you can use an interface more or less the same way you use an abstract class. For example, you can use an interface as a data type for a variable, as the result of casting, and so on. > An interface is treated like a special class in Java. Each interface is compiled into a separate bytecode file, just like a regular class. Like an abstract class, you cannot create an instance from an interface using the new operator, but in most cases you can use an interface more or less the same way you use an abstract class. For example, you can use an interface as a data type for a variable, as the result of casting, and so on.
> >
> 接口如同一个特殊的类(class),每个接口被编译成一个立的字节代码(bytecode... > 接口如同一个特殊的类(class),每个接口被编译成一个立的字节代码(bytecode...
> >
> 接口不能被实例化(使用new关键字),但是可以作为引用变量来引用实现了该接口的类的对象;这种情况下,接口的使用如同抽象类。 > 接口不能被实例化(使用new关键字),但是可以作为引用变量来引用实现了该接口的类的对象;这种情况下,接口的使用如同抽象类。
@@ -408,7 +408,7 @@ public interface Edible {
1. 定义一个接口Edible(可食用的),其中包含一个抽象函数,返回如何烹饪的字符串描述;显然作为可食用这种能力(特性),在大自然中并不是某个类属所拥有的,而是跨越类属的一般特性;某些植物可以食用,某些动物可以食用;但不是所有的动物或者植物都可以食用。 1. 定义一个接口Edible(可食用的),其中包含一个抽象函数,返回如何烹饪的字符串描述;显然作为可食用这种能力(特性),在大自然中并不是某个类属所拥有的,而是跨越类属的一般特性;某些植物可以食用,某些动物可以食用;但不是所有的动物或者植物都可以食用。
2. 作为动物(这里应该是脯乳动物),可以发声是脯乳动物的的共性,但是发出什么样的声音确是每个种类都不一样。因此定义了一个抽象相类Animal,有个抽象方法:sound。 2. 作为动物(这里应该是脯乳动物),可以发声是脯乳动物的的共性,但是发出什么样的声音确是每个种类都不一样。因此定义了一个抽象相类Animal,有个抽象方法:sound。
上图中,虚线箭头表示接口实现,实线表示类继承(扩展)关系。上图中可以看到,水果(Fruit)都是可以食用的,因此水果这个抽象类(斜体表示)实现了可食用的接口;Chicken和Tiger都可以发声,因此由Animal这个抽象类扩展而来,且实现了发的这个抽象方法;动物中只有Chicken可以食用,因此Chicken还实现了可食用的接口。 上图中,虚线箭头表示接口实现,实线表示类继承(扩展)关系。上图中可以看到,水果(Fruit)都是可以食用的,因此水果这个抽象类(斜体表示)实现了可食用的接口;Chicken和Tiger都可以发声,因此由Animal这个抽象类扩展而来,且实现了发的这个抽象方法;动物中只有Chicken可以食用,因此Chicken还实现了可食用的接口。
在代码中,先看看抽象类Animal 在代码中,先看看抽象类Animal
@@ -469,7 +469,7 @@ class Tiger extends Animal {
} }
``` ```
Chicken很特殊,既可以发声,又能食用,因此由Anamal扩展而来,且实现Edible的接口: Chicken很特殊,既可以发声,又能食用,因此由Animal扩展而来,且实现Edible的接口:
```java ```java
class Chicken extends Animal implements Edible { class Chicken extends Animal implements Edible {
+2 -2
View File
@@ -182,7 +182,7 @@ public class InputMismatchExceptionDemo {
1. try语法块是你需要运行的代码,且这些代码可能会产生异常; 1. try语法块是你需要运行的代码,且这些代码可能会产生异常;
2. 当try块中的代码抛出了异常,程序会立即进入到 catch 语法块,且catch后面的参数携带了一个被抛出的异常对象,该对象有异常发生时的全部信息(调用栈,异常描述等等)。 2. 当try块中的代码抛出了异常,程序会立即进入到 catch 语法块,且catch后面的参数携带了一个被抛出的异常对象,该对象有异常发生时的全部信息(调用栈,异常描述等等)。
3. cache块可以通过这个异常对象(上述是ex这个对象),对异常进行处理。 3. catch块可以通过这个异常对象(上述是ex这个对象),对异常进行处理。
这就是基本的异常处理。 这就是基本的异常处理。
@@ -463,7 +463,7 @@ public class InvalidRadiusException extends Exception {
} }
``` ```
![image-20260410132946665](/run/media/danny/Data/CUIT/Java-Book/04:异常处理/img/image-20260410132946665.png) ![image-20260410132946665](img/image-20260410132946665.png)
TestCircleWithCustomException.java TestCircleWithCustomException.java
+4 -4
View File
@@ -1,6 +1,6 @@
> The File class is intended to provide an abstraction that deals with most of the machine-dependent complexities of files and path names in a machine-independent fashion. The filename is a string. The File class is a wrapper class for the file name and its directory path. > The File class is intended to provide an abstraction that deals with most of the machine-dependent complexities of files and path names in a machine-independent fashion. The filename is a string. The File class is a wrapper class for the file name and its directory path.
> >
> 文件类提供了一个与机器(操作系统)无关的文件和路径操作的封装;文件类主要用作文件名和路径的操作,并不对文件本的内容进行操作。 > 文件类提供了一个与机器(操作系统)无关的文件和路径操作的封装;文件类主要用作文件名和路径的操作,并不对文件本的内容进行操作。
注意: 注意:
@@ -65,7 +65,7 @@ public class TestFileClass {
### 2.1. PrintWrite类 ### 2.1. PrintWriter
![image-20230324145547079](img/image-20230324145547079.png) ![image-20230324145547079](img/image-20230324145547079.png)
@@ -110,7 +110,7 @@ Eric K Jones 85
**注意:File对象没有close()方法,因为File对象不对文件的具体内容进行操作。** **注意:File对象没有close()方法,因为File对象不对文件的具体内容进行操作。**
主函数是有返回值的,返回一个整数;对于多数操作系统来说,返回值代表程序是否运行成功;一般返回值是0代表成功,没有错误;非零代表有错误。 主函数可以带返回值吗?main函数的返回值是void,因此没有返回值。这里是指系统命令的执行退出码,如果需要返回给操作系统一个值,可以使用System.exit(返回值);对于多数操作系统来说,返回值代表程序是否运行成功;一般返回值是0代表成功,没有错误;非零代表有错误。
### 2.2. 不要别忘记关闭文件 ### 2.2. 不要别忘记关闭文件
@@ -231,6 +231,6 @@ public class ReadFileFromURL {
1. 掌握File类的基本使用; 1. 掌握File类的基本使用;
2. 掌握PrintWriter的基本使用; 2. 掌握PrintWriter的基本使用;
3. 掌握Scnner读取文本文件内容的基本使用; 3. 掌握Scanner读取文本文件内容的基本使用;
4. 了解 try(...){...}语法; 4. 了解 try(...){...}语法;
5. 5.
+4 -4
View File
@@ -76,13 +76,13 @@ classDiagram
分离读/写主要目的是因为有些类只需要读取或者写入功能。 分离读/写主要目的是因为有些类只需要读取或者写入功能。
**注意:InputStream(读);OutputStream(写)这两个类不是只针对文件系统,凡是可以进行字节读写的类都可以由这两个类进行扩展(例如网络中的通讯)。从这里可以看到,Java不仅仅是面向对象的语言,由于Java提供了一套基本的API(类),使得java也是一套编码规范或者是框架。多数情况下,需要满足Java中基本类型和接口的继承,才能使程序更具有通用性。** **注意:InputStream(读);OutputStream(写)这两个类不是只针对文件系统,凡是可以进行字节读写的类都可以由这两个类进行扩展(例如网络中的通讯)。从这里可以看到,Java不仅仅是面向对象的语言,由于Java提供了一套基本的API(类),使得Java也是一套编码规范或者是框架。多数情况下,需要满足Java中基本类型和接口的继承,才能使程序更具有通用性。**
#### 1.2.1. InputStream #### 1.2.1. InputStream
![image-20230326144650268](img/image-20230326144650268.png) ![image-20230326144650268](img/image-20230326144650268.png)
**注意:`read()`函数后面的返回标注的是int,其实返回的值是0~255。因为java没有unsigned类型,byte类型的取值范围达不到0~255,所以使用int作为返回。** **注意:`read()`函数后面的返回标注的是int,其实返回的值是0~255。因为Java没有unsigned类型,byte类型的取值范围达不到0~255,所以使用int作为返回。**
可以看到有多个关于读的函数,具体含义看书上的解释。 可以看到有多个关于读的函数,具体含义看书上的解释。
@@ -357,8 +357,8 @@ seek用于将文件指针移动到绝对位置。文件指针指向的是当前
## 3. 本章重点 ## 3. 本章重点
1. 理解ImputStream和OutStrem以及子类间的关系; 1. 理解InputStream和OutputStream以及子类间的关系;
2. 掌握FileInputStream和FileOutputStream的基本使用; 2. 掌握FileInputStream和FileOutputStream的基本使用;
3. 理解随文件访问对象RandomAccessFile的使用; 3. 理解随文件访问对象RandomAccessFile的使用;
4. 其他部分是了解。 4. 其他部分是了解。
+1 -1
View File
@@ -102,7 +102,7 @@ arrayList.add(0, 10); // 错误:Collection 没有这样的函数能力描述
arrayList.add(3, 30); // 错误:Collection 没有这样的函数能力描述 arrayList.add(3, 30); // 错误:Collection 没有这样的函数能力描述
``` ```
那么`arrayList.add(0, 10);`这样的代码将错误,因为能力描述是Coolection,虽然对象是ArrayList具备`add(0, 10)`这样的能力,但是arrayList的变量类型是Collection,并不知道对象有这样的能力,因此如果要使用`add(0, 10)`这样的能力,需要进行类型转换: 那么`arrayList.add(0, 10);`这样的代码将错误,因为能力描述是Collection,虽然对象是ArrayList具备`add(0, 10)`这样的能力,但是arrayList的变量类型是Collection,并不知道对象有这样的能力,因此如果要使用`add(0, 10)`这样的能力,需要进行类型转换:
```java ```java
Collection<Integer> arrayList = new ArrayList<Integer>(); Collection<Integer> arrayList = new ArrayList<Integer>();
+4 -4
View File
@@ -1,4 +1,4 @@
Set(集合)与Map是用得非常多的,有别于有序容器的另外一类容器。集合的概念与数学中的集合概念一致(多值,且不重复),这个需要和List等容器进行区别,List等前面学习的容可以在一个容器中包含多个相同的值,但是Set集合却不行。Map是一种特殊的容器,或者被称为Key-Value容器,一个记录包含两个值,其中Key是索引,有点像数据库中的表。 Set(集合)与Map是用得非常多的,有别于有序容器的另外一类容器。集合的概念与数学中的集合概念一致(多值,且不重复),这个需要和List等容器进行区别,List等前面学习的容可以在一个容器中包含多个相同的值,但是Set集合却不行。Map是一种特殊的容器,或者被称为Key-Value容器,一个记录包含两个值,其中Key是索引,有点像数据库中的表。
## 1. Collection的Set接口 ## 1. Collection的Set接口
@@ -51,7 +51,7 @@ HashSet set = new HashSet<String>();
Collection<String> set = new HashSet<String>(); Collection<String> set = new HashSet<String>();
``` ```
也是可以了,引用变量只是能力明。 也是可以了,引用变量只是能力明。
另外需要注意:Set是无序的,没有index的概念,不能使用下标来引用其中的元素,因此无法使用传统的for循环,只能使用如上述的增强for循环。 另外需要注意:Set是无序的,没有index的概念,不能使用下标来引用其中的元素,因此无法使用传统的for循环,只能使用如上述的增强for循环。
@@ -108,7 +108,7 @@ public class CountKeywords {
> The Map interface maps keys to the elements. The keys are like indexes. In List, the indexes are integer. In Map, the keys can be any objects. > The Map interface maps keys to the elements. The keys are like indexes. In List, the indexes are integer. In Map, the keys can be any objects.
> >
> Map 接口中,每个元素都是一个key-value的映射。Key如同是索引,在数组中索引是整integer),在Map中,Key可以是任何的引用类型(Object及其子对象)。 > Map 接口中,每个元素都是一个key-value的映射。Key如同是索引,在数组中索引是整integer),在Map中,Key可以是任何的引用类型(Object及其子对象)。
> >
> >
@@ -149,7 +149,7 @@ public class TestMap {
hashMap.put("Anderson", 31); hashMap.put("Anderson", 31);
hashMap.put("Lewis", 29); hashMap.put("Lewis", 29);
hashMap.put("Cook", 29); hashMap.put("Cook", 29);
hashMap.put("Cook", 31); // 修改 Cooke 的值为 31,以前Cooke为29的被改写了 hashMap.put("Cook", 31); // 修改 Cook 的值为 31,以前Cooke为29的被改写了
System.out.println("Display entries in HashMap"); System.out.println("Display entries in HashMap");
System.out.println(hashMap + "\n"); System.out.println(hashMap + "\n");
+3 -3
View File
@@ -1,4 +1,4 @@
## 面向对象程序设计(JAVA) ## 面向对象程序设计(JAVA
1. [第一章:概述](01%EF%BC%9A%E6%A6%82%E8%BF%B0/01.md) 1. [第一章:概述](01%EF%BC%9A%E6%A6%82%E8%BF%B0/01.md)
2. 第二章:Java语言基础 2. 第二章:Java语言基础
@@ -17,7 +17,7 @@
5. 第五章:IO编程 5. 第五章:IO编程
1. [文件类和文本文件](05%EF%BC%9AIO%E7%BC%96%E7%A8%8B/01.md) 1. [文件类和文本文件](05%EF%BC%9AIO%E7%BC%96%E7%A8%8B/01.md)
2. [二进制文件](05%EF%BC%9AIO%E7%BC%96%E7%A8%8B/02.md) 2. [二进制文件](05%EF%BC%9AIO%E7%BC%96%E7%A8%8B/02.md)
6. 第六章:集合框架 6. 第六章:集合框架
1. [有序容器](06%EF%BC%9A%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6/01.md) 1. [有序容器](06%EF%BC%9A%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6/01.md)
2. [Set和Map](06%EF%BC%9A%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6/02.md) 2. [Set和Map](06%EF%BC%9A%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6/02.md)
@@ -26,4 +26,4 @@
1. [附录1 课程设置](%E9%99%84%E5%BD%95/%E9%99%84%E5%BD%951%20%E8%AF%BE%E7%A8%8B%E8%AE%BE%E7%BD%AE.md) 1. [附录1 课程设置](%E9%99%84%E5%BD%95/%E9%99%84%E5%BD%951%20%E8%AF%BE%E7%A8%8B%E8%AE%BE%E7%BD%AE.md)
2. [附录2 拼题平台的使用](%E9%99%84%E5%BD%95/%E9%99%84%E5%BD%952%20%E6%8B%BC%E9%A2%98%E5%B9%B3%E5%8F%B0%E7%9A%84%E4%BD%BF%E7%94%A8.md) 2. [附录2 拼题平台的使用](%E9%99%84%E5%BD%95/%E9%99%84%E5%BD%952%20%E6%8B%BC%E9%A2%98%E5%B9%B3%E5%8F%B0%E7%9A%84%E4%BD%BF%E7%94%A8.md)
有问题,请提交[问题提交](https://gitee.com/gaohongy/Java-Book/issues/new) 有问题,请[问题提交](https://gitee.com/gaohongy/Java-Book/issues/new)反馈
+110
View File
@@ -0,0 +1,110 @@
# 文档审核修正报告
**扫描范围**:全部 19 个文档
**修正文件**17 个
**累计修改**88 处
> 审核时间:2026-06-10
> 审核类型:错别字、术语一致性、逻辑错误、格式错误
---
## 1. 错别字修正(51 处)
| 错误 | 修正 | 涉及文件 | 修改处数 |
|------|------|----------|:--------:|
| `本生` | `本身` | 01/01.md, 03/01.md, 05/01.md | 4 |
| `相识` | `相似` | 01/01.md | 1 |
| `一给` | `一个` | 02/01.md | 1 |
| `之需要` / `只` | `只需要` / `指` | 01/01.md, 02/02.md, 02/01.md | 4 |
| `字文件夹` | `子文件夹` | 01/01.md | 1 |
| `申明` | `声明` | 01/01.md, 03/03.md, 03/04.md, 06/02.md | 6 |
| `java`(说明文字中) | `Java` | 01/01.md, 02/05.md, 02/06.md, 03/03.md, 05/02.md | 13 |
| `产程` | `产生` | 02/05.md | 1 |
| `肯能` | `可能` | 02/05.md | 1 |
| `到达` | `到大` | 02/06.md | 1 |
| `有叫做` | `又叫做` | 01/01.md | 1 |
| `一致` | `一直` | 02/05.md | 1 |
| `warp` | `wrapper` | 03/01.md | 1 |
| `整形` | `整型` | 06/02.md | 1 |
| `Interger` | `Integer` | 02/03.md | 1 |
| `一窜` | `一串` | 02/06.md | 1 |
| `Anamal` | `Animal` | 03/04.md | 1 |
| `Coolection` | `Collection` | 06/01.md | 1 |
| `Scnner` | `Scanner` | 05/01.md | 1 |
| `netDouble` | `nextDouble` | 02/01.md | 1 |
| `PrintWrite` | `PrintWriter` | 05/01.md | 1 |
| `cache` | `catch` | 04/01.md | 1 |
| `ImputStream` | `InputStream` | 05/02.md | 1 |
| `OutStrem` | `OutputStream` | 05/02.md | 1 |
| `随即` | `随机` | 05/02.md | 1 |
| `需熬` | `需要` | 附录2 | 1 |
| `复数` | `负数` | 03/01.md | 1 |
| `Souorce` | `Source` | 01/01.md | 1 |
| `Ctl` | `Ctrl` | 01/01.md, 02/01.md | 2 |
| `Spring` | `String` | 03/01.md | 1 |
| `我么` | `我们` | 03/01.md | 1 |
| `extend` | `extends` | 03/03.md | 1 |
| `sclass` | `class` | 03/03.md | 1 |
| `上诉` | `上述` | 03/03.md | 1 |
| `开起来` | `看起来` | 03/03.md | 1 |
| `文件间` | `文件` | 03/03.md | 1 |
| `对立的` | `独立的` | 03/04.md | 1 |
| `发生的` | `发声的` | 03/04.md | 1 |
| `impliment` | `implement` | 03/04.md | 1 |
| `你的你` | `你的` | 附录2 | 1 |
| `容易` | `容器` | 06/02.md | 1 |
| `Cooke` | `Cook` | 06/02.md | 1 |
| `pringInfo` | `printInfo` | 03/03.md | 1 |
| `nullFunxtion` | `nullFunction` | 02/05.md | 1 |
| `字面量量` | `字面量` | 03/02.md | 1 |
| `大头` | `开头` | 03/02.md | 1 |
| `区别于动态` | `区别于静态` | 03/01.md | 1 |
## 2. 逻辑问题修正(3 处)
| 文件 | 行号 | 问题描述 | 处理方式 |
|------|:----:|----------|----------|
| 05/01.md | 113 | 描述"主函数有返回值"——main返回void | 修正为系统退出码说明 |
| 01/01.md | 296 | 字符串中混入API定义文字 | 移除乱入文本 |
| 01/01.md | 310 | "组织的,的"多余标点 | 移除多余标点 |
## 3. 格式与路径修正(2 处)
| 文件 | 问题 | 处理 |
|------|------|------|
| 04/01.md | 图片使用了绝对路径 | 改为相对路径 |
| README.md | `JAVA)` 括号不匹配 | 改为 `JAVA` |
| README.md | `集合与框架`与目录名不一致 | 改为 `集合框架` |
| README.md | 问题反馈表述重复 | 优化措辞 |
## 4. 未修正的已发现问题(保留,非错误)
以下问题经评估属于可接受范围,未作修改:
- 部分中英文标点混用(如中文句号与英文句点交替出现)——全文风格一致,不做统一
- 部分 Mermaid 图表中的 Unicode 类名(如"脯乳动物")——Mermaid 渲染需保留原始字符
- 个别术语翻译差异(如"抽象相类Animal")——保留原文特色
## 5. 各文件修改统计
| 文件 | 修改处数 |
|------|:--------:|
| 01:概述/01.md | 21 |
| 02Java语言基础/01.md | 6 |
| 02Java语言基础/02.md | 2 |
| 02Java语言基础/03.md | 2 |
| 02Java语言基础/05.md | 6 |
| 02Java语言基础/06.md | 6 |
| 03:类与对象/01.md | 8 |
| 03:类与对象/02.md | 2 |
| 03:类与对象/03.md | 11 |
| 03:类与对象/04.md | 6 |
| 04:异常处理/01.md | 2 |
| 05IO编程/01.md | 4 |
| 05IO编程/02.md | 4 |
| 06:集合框架/01.md | 1 |
| 06:集合框架/02.md | 4 |
| README.md | 3 |
| 附录/附录2 拼题平台的使用.md | 2 |
| **合计** | **88** |
+2 -2
View File
@@ -72,7 +72,7 @@ https://oms.pintia.cn/download-oms-client?tab=self-check
![1677660511748.png](./img/1677660511748.png) ![1677660511748.png](./img/1677660511748.png)
上图中,左边是你的运行结果;右边是正确的运行结果。(3)位置处标识了你运行结果和预期结果的不同。这个例子中你运行结果的最后一行多了一个回车。一般来说,最后一行多一行回车没有什么关系,会被判定为正确。 上图中,左边是你的运行结果;右边是正确的运行结果。(3)位置处标识了你运行结果和预期结果的不同。这个例子中你运行结果的最后一行多了一个回车。一般来说,最后一行多一行回车没有什么关系,会被判定为正确。
如果程序编译错误,在运行后会出现编译错误界面,可以根据该界面去排错,如下图: 如果程序编译错误,在运行后会出现编译错误界面,可以根据该界面去排错,如下图:
@@ -92,7 +92,7 @@ https://oms.pintia.cn/download-oms-client?tab=self-check
左边是题面,右边是你的提交代码。可以看到,右边并没有完整的主类定义,而主类的定义在左边的题面中。 左边是题面,右边是你的提交代码。可以看到,右边并没有完整的主类定义,而主类的定义在左边的题面中。
如果你需在Eclipse中调试代码,需要将左边题面部分的代码复制到Eclipse当中,然后在提示的位置编写你的答案。 如果你需在Eclipse中调试代码,需要将左边题面部分的代码复制到Eclipse当中,然后在提示的位置编写你的答案。
==注意:函数题一般是写类或者是接口的定义,这些类或者是接口不能使用 public 进行修饰,因为在一个Java文件中只能有一个 public类,这个类就是主类。== ==注意:函数题一般是写类或者是接口的定义,这些类或者是接口不能使用 public 进行修饰,因为在一个Java文件中只能有一个 public类,这个类就是主类。==