CS61B学习笔记(二)--Reading.1.Introducing
1.1 要点 ·拥抱61B — 1.1 Essentials · Hug61B (gitbooks.io)
要点
Hello world
1 | public class HelloWorld { |
System.out.println("Hello world!");
相当于与c++中的cout<<"Hello world!"<<endl;
System.out.print("Hello world!");
相当于与c++中的cout<<"Hello world!";
对于那些来自像 Python 这样的语言的人来说,这似乎毫无必要地冗长。然而,这一切都是有充分理由的,我们将在接下来的几周内理解这一点。需要注意的一些关键语法特征:
- 该程序由一个类声明组成,该声明使用关键字
public class
声明。在 Java 中,所有代码都位于类中。 - 运行的代码位于名为
main
的方法中,该方法声明为public static void main(String[] args)
。 - 我们使用大括号
{
和来表示一段代码的开头和}
结尾。 - 语句必须以分号结尾。
运行 Java 程序
执行 Java 程序的最常见方法是通过两个程序的序列运行它。第一种是 Java 编译器,或 javac
.第二个是 Java 解释器,或 java
.
![image-20240118035144027](2-CS61B学习笔记-Reading.1.Introducion to Java/image-20240118035144027.png)
例如,要运行 HelloWorld.java
,我们会在终端中键入命令,然后键入命令 javac HelloWorld.java
java HelloWorld
。结果如下所示:
1 | $ javac HelloWorld.java |
在上图中,$ 表示我们终端的命令提示符。
您可能会注意到,我们在编译时包含“.java”,但在解释时不包括“.class”。这就是它的方式(TIJTWII)。
代码样式、注释、Javadoc
代码在很多方面都很漂亮。它可以很简洁。它可以很聪明。它可以是有效的。新手最不被重视的代码方面之一是代码风格。当你作为一个新手编程时,你往往一心一意地让它工作,而不考虑再看一遍或不得不长时间维护它。
在本课程中,我们将努力保持代码的可读性。良好的编码风格的一些最重要的特征是:
- 一致的样式(间距、变量命名、大括号样式等)
- 大小(行不要太宽,源文件不要太长)
- 描述性命名(变量、函数、类),例如名称为
year
or 而不是x
orf
getUserName
的变量或函数。 - 避免重复代码:除了一些更改外,几乎不应该有两个几乎相同的重要代码块。
- 酌情注释。Java 中的行注释使用
//
分隔符。阻止(又名多行注释)注释 use/*
和*/
.
黄金法则是:编写代码,以便陌生人易于理解。
Style Guide | CS 61B Spring 2019 (datastructur.es)这是该课程的官方风格指南。值得一看!
注释
所有方法和几乎所有类都应该使用所谓的 Javadoc 格式在注释中进行描述。在 Javadoc 注释中Javadoc - 维基百科,自由的百科全书 — Javadoc - Wikipedia,块注释以额外的星号开头,例如 /**
,并且注释通常(但并非总是)包含描述性标记。我们不会在本教科书中讨论这些标签,但请参阅上面的链接以了解它们的工作原理。
需要特别注意的是,所有方法和几乎所有类都应该使用所谓的 Javadoc 格式在注释中进行描述。在 Javadoc 注释中,块注释以额外的星号开头,例如 /**
,并且注释通常(但并非总是)包含描述性标记。我们不会在本教科书中讨论这些标签,但请参阅上面的链接以了解它们的工作原理。
举个没有标签的例子:
1 | public class LargerDemo { |
广泛使用的 javadoc 工具javadoc (oracle.com)可用于生成代码的 HTML 描述。
对象
定义和使用类
Java 中的所有代码都必须是类的一部分(或类似于类的东西,我们将在后面学习)。大多数代码都是在方法内部编写的。让我们考虑一个例子:
1 | public class Dog { |
如果我们尝试运行该 Dog
类,我们只会收到一条错误消息:
1 | $ java Dog |
我们定义的 Dog
类不执行任何操作。我们只是定义了一些 Dog
可以做的事情,即制造噪音。要实际运行该类,我们需要向 Dog
该类添加一个 main 方法,正如我们在第 1.1 章中看到的那样。或者我们可以创建一个单独的 DogLauncher
类来运行该 Dog
类的方法。例如,考虑以下程序:
1 | public class DogLauncher { |
1 | $ java DogLauncher |
使用另一个类的类有时称为该类的“客户端”,即 DogLauncher
是 Dog
的客户端。这两种技术都不是更好的:在某些情况下,添加 main 方法可能更好,而在其他情况下创建类似 client 类 Dog
DogLauncher
可能更好。随着我们在整个课程中获得额外的练习,每种方法的相对优势将变得清晰。
因此总结下:
- 类的使用有两种方法:
- 一种是带有main方法的类
- 一种是只有方法,由另一个类来调用。
静态方法 vs 非静态方法
同cpp
的知识点,静态方法属于类,非静态方法属于对象(实例)。调用静态方法时,通常用类名.方法
,调用非静态方法时通常用对象名.方法
。
对比上下两个Dog
类的makeNoise
方法可以发现,在加上条件判断语句前为静态方法,加上后变为非静态方法,说明是不同体重对象的方法。
详细下面有说
实例变量和对象实例化
并非所有的狗都是一样的。有些狗喜欢不停地吠叫,而另一些狗则发出铿锵有力的咆哮,给所有听到它们光荣呼唤的人带来欢乐。通常,我们编写程序来模仿我们居住的宇宙的特征,而 Java 的语法很容易允许这种模仿。
允许我们表示 Dogdom 光谱的一种方法是为每种类型的 Dog 创建单独的类。
1 | public class TinyDog { |
正如您过去应该看到的,类可以实例化,实例可以保存数据。这导致了一种更自然的方法,我们创建 Dog
类的实例,并使 Dog
方法的行为取决于特定 Dog
.为了更具体地说明这一点,请考虑以下类:
1 | public class Dog { |
作为使用这种狗的例子,请考虑:
1 | public class DogLauncher { |
一些关键观察结果和术语:
- Java 中的
Object
是任何类的实例。 - 该
Dog
类有自己的变量,也称为实例变量或非静态变量。这些必须在类中声明,这与 Python 或 Matlab 等语言不同,后者可以在运行时添加新变量。 - 我们在
Dog
类中创建的方法没有关键字static
。我们将此类方法称为实例方法或非静态方法。 - 要调用该
makeNoise
方法,我们必须首先使用new
关键字实例化 aDog
,然后制作特定的Dog
bark。换句话说,我们调用d.makeNoise()
了Dog.makeNoise()
. - 一旦一个对象被实例化,就可以将其分配给适当类型的声明变量,例如
d = new Dog();
- 类的变量和方法也称为类的成员。
- 使用点表示法访问类的成员。
类方法与实例方法
Java 允许我们定义两种类型的方法:
- 类方法,又名静态方法。
- 实例方法,又名非静态方法。
实例方法是只能由类的特定实例执行的操作。静态方法是由类本身执行的操作。两者在不同情况下都很有用。作为静态方法的示例,该 Math
类提供了一个 sqrt
方法。因为它是静态的,我们可以这样称呼它:
1 | x = Math.sqrt(100); |
如果 sqrt
是一个实例方法,我们将得到下面笨拙的语法。幸运的是,它是一种 sqrt
静态方法,因此我们不必在实际程序中执行此操作。
1 | Math m = new Math(); |
有时,拥有一个同时具有实例和静态方法的类是有意义的。例如,假设想要比较两只狗的能力。一种方法是添加一个用于比较 Dogs 的静态方法。
1 | Dog d = new Dog(15); |
请注意,我们已使用类名调用,因为此方法是静态方法。
我们也可以 maxDog
实现为非静态方法,例如
1 | public Dog maxDog(Dog d2) { |
上面,我们使用关键字 this
来指代当前对象。例如,可以使用以下方法调用此方法:
1 | Dog d = new Dog(15); |
静态变量
类具有静态变量有时很有用。这些是类本身固有的属性,而不是实例的属性。例如,我们可以记录狗的学名(或双子)是Canis familiaris
:
1 | public class Dog { |
静态变量应该使用类的名称而不是特定的实例来访问,例如,您应该使用 Dog.binomen
,而不是 d.binomen
.
虽然 Java 在技术上允许你使用实例名称访问静态变量,但它的风格很糟糕,令人困惑,而且在我看来是 Java 设计者的错误。(不是我的评价)
Java的构造函数
1 | public class Dog { |
每当我们尝试 Dog
创建 using new
关键字和单个整数参数时,都会调用带有签名 public Dog(int w)
的构造函数。对于那些来自 Python 的人来说,构造函数与 __init__
方法非常相似。
数组实例化,对象数组
1 | public class DogArrayDemo { |
请注意,new 以两种不同的方式使用:一次用于创建一个可以容纳两个 Dog
对象的数组,两次用于创建每个实际 Dog
的 .
public static void main(String[] args)的说明
根据我们目前所学到的知识,是时候揭开我们一直用于 main 方法的声明的神秘面纱了。把它分成几块,我们有:
public
:到目前为止,我们所有的方法都以这个关键字开头。- static` :它是一个静态方法,不与任何特定实例关联。
void
:它没有返回类型。main
:这是方法的名称。String[] args
:这是传递给 main 方法的参数。
命令行参数
由于 main 是由 Java 解释器本身调用的,而不是由另一个 Java 类调用的,因此解释器的工作是提供这些参数。它们通常引用命令行参数。例如,考虑以下程序 ArgsDemo
:
1 | public class ArgsDemo { |
该程序打印出第 0 个命令行参数,例如
1 | $ java ArgsDemo these are command line arguments |
在上面的示例中,将是一个字符串数组, args
其中条目为 {“these”, “are”, “command”, “line”, “arguments”}。
这样子可以识别命名 -m -v 等