6. 从 Python 到 Java 教程¶
学过 CS2064(由 John Wenskovitch 提供)的学生可以选择复习 Python 与 Java 的差异。推荐给有 Python 背景但 Java 经验不多的学生。
6.1. 代码块¶
在 Python 中,我们通过以冒号结束 for 、 if 、 def 或 class 行,然后缩进希望包含在代码块中的代码来创建代码块。在 Java 中,空白无关紧要,但为了可读性,我们仍然按惯例缩进代码。我们不使用空白来创建代码块,而是用 { 字符打开代码块,用 } 字符关闭它。我已经养成了在注释中注明正在关闭哪个代码块的习惯(例如 } //if ),但这并非必需。
6.2. 分号¶
在 Java 中,每条语句都以分号结尾。注意,条件、循环或函数/方法/类代码块的开始并不算一条语句;那些行仍然以左花括号结尾。
6.3. 变量类型¶
Python 很擅长判断你打算在变量中存储什么类型的数据——例如,定义 a=7 就足以让 Python 知道 a 是整数类型。当然,在处理某些数据结构时,你必须先创建结构,然后才能开始修改它(例如,在调用 myList.append() 之前先创建 myList=[] )。在 Java 中,所有变量在使用前都必须定义相关联的类型。为了让 a 成为整数,你需要把它定义为 int a 。你可以把变量定义作为单独的步骤,也可以把定义和初始化合在一起(例如 int a=7 )。大多数类型与你在 Python 的 type() 函数中找到的相同,但 String 类型是一个特例,因为在 Java 中字符串不是原始类型(它反而是一个类),所以该类型是以大写 S 定义。
6.4. 实例变量¶
在 Python 中,当在类中使用变量时,我们通常只在构造函数中给它赋一个默认值就完事了。由于这些变量需要类型化,并且还要能在构造函数之外访问(见下面的“作用域”),在 Java 中,我们会在类的所有方法之外定义它们。就这个 Rational 类而言,你会看到我们已经为你定义了 private int numerator 和 private int denominator 。这些不应更改。
6.5. 方法的返回类型¶
与定义变量类型类似,Java 也会要求你定义方法或函数返回的变量类型。如果方法或函数不返回任何内容,那么返回类型就是 void 。
6.6. 构造函数¶
在 Python 中创建类时,我们使用 __init__() 来定义类的构造函数。在 Java 中,构造函数的名字必须与类的名字一致,所以定义类 Rational 意味着你的文件将被命名为 Rational.java ,而你的构造函数将被命名为 Rational() 。构造函数总是 public(见下一条),而且没有返回类型。当你调用构造函数创建新对象时,必须使用 new 关键字:
//use the new keyword to create a new instance of a class
Rational r = new Rational(1, 3);
6.7. 访问控制修饰符¶
在 Python 中,可以通过在变量开头加一对下划线,把变量变为类的 局部 变量(还记得 __numerator 和 __denominator 吗?)。在 Java 中,我们还有额外的关键字来控制对变量和方法的访问。
将变量或方法声明为
public允许从任何地方访问它。使用
protected关键字,允许从本类、任何子类以及同一包中的任何其他类访问它。private修饰符使某些内容只能对本类可见。- 我们这次 Java 作业的约定是:
所有实例变量都是 private。
任何需要从类外部访问的方法都应该是
public,否则应该是private。本课程不需要
protected修饰符。
self与this:在 Python 中,我们用self指代当前对象。在 Java 中,做同样事情的关键字是this。Java 的一个便利之处在于,我们不需要像使用self那样把 this 传给每个方法;这在后台已经帮我们处理好了。
6.8. 作用域¶
Python 和 Java 的作用域规则在类、方法和函数方面是相同的——在这些代码块内定义的变量只在这些代码块内是局部的。在 Java 中,条件和循环也有相同的作用域规则——如果你在 for 循环内定义一个变量,它就只在该 for 循环内可访问。
6.9. 条件与循环语法¶
在 Python 中,条件和循环的格式相当宽松。Java 更严格,但对两个代码块的定义来说也更一致。最值得注意的是,循环参数和条件都必须用括号括起来。注意,下面循环示例中的 j++ 是 j+=1 或 j=j+1 的另一种简写:
下面是一些示例:
// conditional
if (a < 7) {
// the commands subject to the conditional
}
//for loop
for (int j = 0; j < 17; j++) {
// the commands subject to the for loop
}
// while loop
while (t < 4) {
//the commands subject to the while loop
}
6.10. 函数与方法语法¶
长话短说,在 Java 中不需要使用 def 关键字。函数是这样定义的:
// Function definitions follow the format of
// <access control> <return type> <function name>(<optional parameters>)
// for example:
public int getDenominator() {
return anInt;
}
public void setDenominator(int d) {
}
6.11. 打印(用于调试)¶
Python 通过随时可用的 print() 函数让打印变得方便。Java 打印需要多打一些字;命令是 System.out.println() (大写的 S 很重要)。Java 让某件事变得简单了一些,就是在同一行打印多个内容。用 Python 时,我们需要在 print 调用中使用带有空字符串的 end 参数(即 print("Hello world!", end="") )。用 Java 时,你只需从函数调用中去掉 ln ,直接使用 System.out.print() 。
//python
print("prints a string WITHOUT a newline at the end", end=""))
print("prints a string WITH a newline at the end")) //notice missing 'end' parameter
//java
System.out.print("prints a string WITHOUT a newline at the end")
System.out.println("prints a string WITH a newline at the end")
6.12. 注释:¶
注释:在 Java 中,用 // 而不是 # 来注释。你还可以用 /* 开始、以 */ 结束的 Java 注释块替代三引号注释块。
//This is a single line comment
/*
This is a comment
that crosses multiple
lines in a java file
*/
6.13. 布尔值:¶
在 Python 中, True 和 False 以大写字母开头。在 Java 中, true 和 false 都是 小写 的。
6.14. 逻辑运算符:¶
在 Python 中,我们拥有方便的逻辑运算符英文写法: and 、 or 和 not 。Java 对逻辑运算使用符号运算符:and 是 &&,or 是 ||,not 是 !。
6.15. 对象比较:¶
在 Python 中,你可以用 == 比较两个对象,视需要借助 __eq__ 覆盖该运算符的行为。Java 不允许我们覆盖比较运算符,所以用 == 比较两个对象时,如果它们指向内存中的同一位置则返回 true,否则返回 false。要在 Java 中比较两个对象,我们应改用 .equals() 方法,而这个方法我们是可以覆盖的。这个被覆盖的方法已经为你提供,细节见下方的方法说明。
