在Java中,所有的代码对象或者软件对象,都是从类创建出来的。在编程术语中,类是从英文单词“Class”直译过来的,有类别、分类的意思。对于Java类,我们可以将其理解成模板或者蓝图,基于这些类在代码中可以很容易创建出不同类别的对象。这就像工人可以基于设计图很快建造出一座座房子一样。
因此在真正构建交通工具对象前,第一步我们需要创建对应的Java类。接下来以汽车为例,让我们一起来看看如何创建一个Car类。
首先在IntelliJ IDEA软件中新创建一个Java工程,不妨将其命名为“FirstJavaClass”。接着在src目录下添加一个Java类,将其命名为Car。
在Java中,创建一个类的基本语法结构如下,
访问限定符 class 类名字 {
...
}
花括号前面的代码通常被叫做类的头部,英文单词是“Class Header”,花括号里面的代码就对应地叫做类体“Class Body”。
访问限定符用来指明我们创建的类有什么样的访问权限,可能是public、private和protected这三个访问限定符中的一个,分别用来指定公开、私有和受保护三种访问权限。关于这几种访问限定符,大家暂时不用了解,后面马上会深入学习它们的使用及区别。
类名字的命名我们很早在命名规范教程中提到过,可以是一个单词或者词组,但是每个单词的首字母都要大写。而且类名字尽量应该是名词或者名词词组。
继续回到IntelliJ IDEA的代码编辑窗口,打开“Car.java”源文件,并删掉软件自动为我们添加的所有代码。现在我们会一步一步编写Car这个Java类的代码部分。
首先是类头部分,为了让情况变得简单,我们默认这个类有公开访问权限。编写完整后的类头部分的代码如下,
public class Car
接下来继续编写类体部分的代码。
类体部分的代码往往定义或者描述了某个类的属性,这些属性包含数据属性和方法属性。在有的Java技术资料中,数据属性也可能被叫做域,英文单词是Field。为了是后续教程的文字表达更简洁,这里统一使用域来表示数据属性。
声明一个域的基本语法结构如下,
访问限定符 数据类型标识符 域名字;
抛开前面的访问限定符,声明域的语法结构与声明变量几乎一样。我们可以在声明域的时候对其进行初始化,也可以在类体的其他地方对其进行初始化。
假设现在我们想要给Car这个类添加两个域来分别表示汽车的gps位置和当前速度,可以这样编写代码,
public String gps;
public int speed;
这段代码中,为了让情况变得简单,所有域的访问权限都是public。第一个域gps是字符串类型,第二个域speed是int类型。
类似地,我们继续声明两个域用来表示汽车是油车、电车,是本地车辆还是入境车辆。
public byte type;
public byte local;
这两个域的类型都是字节类型。从开发需求上我们可以这样定义,当域type的值为0时表示油车,为1时表示电车;同理,当域local的值为0时表示车辆为本地车辆,为1则表示其是入境车辆。
编写完域部分的代码后,我们继续来看看如何声明类的方法属性。
声明方法属性或者方法的基本语法结构如下,
访问限定符 类型标识符 方法名字(方法参数) {
...
}
对比声明一个类的语法结构,我们可以将花括号前面的代码叫做方法头,英文是“Method Header”,花括号里面的是方法体,“Method Body”。
与前面一样,访问限定符可能是public、private、protected中的某一个,用来指明我们的方法有什么样的的访问权限。
类型标识符用来指明我们的方法在运行成功后会返回什么类型的数据,如果方法不返回数据,则应该使用void保留关键词来标识。
方法名字的取法应该满足命名规范,通常意义上应该是一个动词或者动词词组,除了第一个单词外其余单词的首字母均应该大写。
方法参数部分用来指明如果要使用这个方法,我们应当对其提供什么类型的数据。当然,并不是所有方法在使用时都需要对其提供数据,对于这类方法我们可以省略方法参数部分的代码。
假设现在我们想要给Car类声明一个方法用来更新每一个汽车(对象)的gps信息,可以这样编写代码,
public void setGps(String gpsP) {
this.gps = gpsP;
}
public访问限定符用来标明setGps()这个方法在代码中的任何地方都可以使用,void类型标识符用来说明这个方法在执行完后不会返回任何数据给执行者。在圆括号()里面是这个方法的参数部分,或者叫做参数定义,用来标明当我们想要使用这个方法时,应该对其传递什么类型的数据。这里我们的方法参数是一个字符串类型,参数名字为gpsP,末尾的大写字母“P”是单词“Parameter”的首字母,添加这样一个后缀是为了与Car这个类的域gps相区分。
因为现在是我们第一次真正意义上接触方法的声明,大家可能不是很容易理解什么是参数,不过不用担心。后面马上我们会学习怎样来使用这些方法,到时候通过更具体可观的例子来帮助大家理解。暂时大家可以将方法参数理解为执行某个方法的上下文信息。
在setGps()这个方法的方法体里面只有一行代码,它的作用是将上下文信息赋给Car类的gps域。这里我们第一次见到this关键词的使用,它用来代表我们使用Car这个类创建的每一个具体的汽车对象。大家暂时不用深入理解this关键词,后面在学习方法的使用时会补充这部分知识。
类似地,我们也可以声明一个方法用来上报每一个汽车对象的gps信息,比如像这样,
public String getGps() {
return this.gps;
}
这个方法也具有公开访问权限,String类型标识符标明getGps()方法执行完后会向执行者返回字符串类型的数据。因为这个方法执行时不需要向其传递数据,因此参数定义部分为空。
在方法体里面也只有一行代码,
return this.gps;
它的作用是向getGps()方法的执行者返回Car类的gps域。这里是我们第一次接触return关键词,暂时不用深入理解它的用法。
上面的示例代码围绕gps这个域声明了setGps()、getGps()两个方法,在Java编程术语中它们还有专门的名称,setter方法和getter方法。通常情况下,setter方法用来更新对象的某个域,而getter方法则用来向执行者返回对象的某个域的最新值。
我们可以依照这种方式,继续围绕speed、type、local其他三个域声明对应的方法。
public void setSpeed(int speedP) {
this.speed = speedP;
}
public int getSpeed() {
return this.speed;
}
public void setType(byte typeP) {
this.type = typeP;
}
public byte getType() {
return this.type;
}
public void setLocal(byte localP) {
this.local = localP;
}
public byte getLocal() {
return this.local;
}
编写完前面这些代码后,我们的Car类的声明过程基本上快要完成了,但是还差最后一步。在所有Java类的类体里面还有一个特殊方法,它的名字与每个类名字相同,常常被叫做构造器方法。构造器方法将会在我们准备基于某个类来创建对象时,首先被执行。
构造器方法(或者构造器)的声明与普通方法的声明基本一样,也需要指定访问限定符,也可能包含参数定义部分。但是构造器方法最大的不同是其没有返回类型,因此就不需要使用类型标识符。此外,构造器方法的访问权限必须是公开的。
下面是我们的Car类的构造器方法的代码,
public Car(String gpsP, int speedP, byte typeP, byte localP) {
this.gps = gpsP;
this.speed = speedP;
this.type = typeP;
this.local = localP;
}
构造器,如果在表述上不需要特别强调它是一个方法时,其主要作用是用来进行对象内部状态的初始化,比如对域进行初始化,包括对部分复合类型的域设置到默认状态。
在编写代码的习惯上,程序员常常将构造器放在域声明代码后面的第一位置。后面的学习过程中,我们也推荐这样。下面是我们的第一个类Car的完整代码。
public class Car {
public String gps;
public int speed;
public byte type;
public byte local;
public Car(String gpsP, int speedP, byte typeP, byte localP) {
this.gps = gpsP;
this.speed = speedP;
this.type = typeP;
this.local = localP;
}
public void setGps(String gpsP) {
this.gps = gpsP;
}
public String getGps() {
return this.gps;
}
public void setSpeed(int speedP) {
this.speed = speedP;
}
public int getSpeed() {
return this.speed;
}
public void setType(byte typeP) {
this.type = typeP;
}
public byte getType() {
return this.type;
}
public void setLocal(byte localP) {
this.local = localP;
}
public byte getLocal() {
return this.local;
}
}
自此,我们的关于汽车这一交通工具的Car类就声明好了,接下来的教程我们会一起学习如何来使用它。