Java 类与对象

“Sometimes we stare so long at a door that is closing that we see too late the one that is open.”

— Alexander Graham Bell, Inventor

「我们有时候专注于消失中的机会太久,以致于太晚发现开启的机会。」– 亚历山大‧贝尔 (发明家)

关卡说明

关卡描述:Java是一门面向对象的语言,类和对象是Java中最重要的概念,本关将介绍这两个重要的概念,并通过一个简单的栗子来进行说明,你能否通过本关的考验呢?

过关条件:理解面向对象编程的特点,理解Java中类和对象的关系,以及如何使用它们

关卡难度:⭐️⭐️

面向对象程序设计

面向对象编程(OOP)是当今主流的程序设计规范,Java是完全面向对象的,所以必须熟悉OOP才能编写出优秀的Java代码。

面向对象编程,顾名思义,重点就在于这个对象,没有对象怎么编程(手动滑稽)。咳咳,言归正传,面向对象的程序是由许许多多的对象组成,每个对象具有一定的属性和行为,通过对象之间的交互来实现软件的功能。从根本上来说,只要这个对象能满足功能要求,就不必关心它的具体实现过程。换句话说,不管是黑猫白猫,能抓耗子的猫就是好猫。

在传统的程序设计过程中,通常需要先设计一系列的算法来求解问题,然后再考虑存储数据的方式。这就是所谓的:

算法 + 数据结构 = 程序

在面向过程的设计中,算法是放在第一位的,数据结构是为了适应算法而存在的。

而OOP中,这个顺序刚好相反,数据结构放在第一位,然后再考虑操作数据的算法。

一些简单的问题,使用面向过程的开发方式是比较容易的。面向对象的编程适合于解决规模较大的问题。比如实现一个网站也许需要1000个过程,这些过程可能会对一组全局的数据进行操作。如果采用面向对象的方式来设计,可能只需要大约100个类,每个类10个方法,而且大多数情况下,面向过程开发的代码中有很多设计是可以使用面向对象的方式简化和复用的。所以后者显然更容易掌握和维护,如果万一某个数据出了问题,在10个方法中排查总比在1000个过程中排查要容易得多。

Java中的类和对象

既然面向对象编程这么优秀,那么我们就来好好认识一下这其中的主人公——类和对象。

“类”表示的是具有相同属性的一系列事物,比如说,“人类”,描述的就是有“人”这个共同属性和行为的群体,“汽车”描述的是有四个轮子,可以驾驶,可以载人的小型车辆,不管你是黑色的奔驰还是银色的宝马,都可以叫做汽车。

那么什么是对象呢?对象就是类的某个具体实例,就好比你和我都是“人类”的一个具体是实例,所以我们都是“人类”的一个对象。你家的那辆汽车(不管是奔驰还是大众),也是“汽车”的一个对象。

类是抽象的概念,而对象则是具体的概念。

类可以看作是对象的模版,一个类可以生成无数个对象。

类的定义

先来看一个小栗子,我们来定义一个人类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Person{
private String name;
private int age;

public Person(String name, int age){
this.name = name;
this.age = age;
}

public void eat(){
System.out.println("开始吃饭...");
}

public void say(){
System.out.println("我叫" + name + ",我今年" + age + "岁");
}
}

这里我们定义了一个类,类的名字叫做Person,它有两个属性,一个是name,一个是age。并且有三个方法,一个是构造函数,两个是Person的行为,吃饭和说话。

可以看到,定义类的时候,我们是这样的:

1
2
3
public class Person{
...
}

定义类的格式为:

[访问权限修饰符] + class + [类名]

其中访问权限修饰符用来表示类是否可以被外部类访问,public是最宽松的访问权限,表示这个类可以被外部的类访问和使用。

class是用来声明一个类的关键字。

关于类名,跟变量名一样,必须以字母开头,可以由字母、数字和下划线和$组成,但跟变量命名不同的是,Java中的类名规范通常使用大驼峰命名法,即每个单词的首字母都大写。比如:SmallCar、SecondhandBook。

类的组成

一个类主要由实例域和方法域组成,实例域由成员变量组成,上面的栗子中,Person类的实例域为:

1
2
private String name;
private int age;

这是Person类的两个成员变量,也叫Person类的属性,一个人有名字和年龄。

接下来是方法域,顾名思义便是由各种方法组成的。方法的定义规则为:

[访问修饰符] + [方法返回值类型] + [方法名]

1
2
3
4
5
6
7
public void eat(){
System.out.println("开始吃饭...");
}

public void say(){
System.out.println("我叫" + name + ",我今年" + age + "岁");
}

这里,void代表方法无返回值。方法的命名跟变量的命名规则一样,也使用小驼峰命名法。需要注意的一点是,无论是类名、方法名还是变量名,都需要具有一定的意义,也就是要能够传达出它代表的含义,做到见名知义。像a1a2这样的命名就尽量不要出现。

也许你会好奇,上面不是还有一个方法吗?为什看起来有点奇怪呢?为什么它不使用小驼峰,为什么它跟类名是一样的?

1
2
3
4
public Person(String name, int age){
this.name = name;
this.age = age;
}

这是一个好问题,它叫做构造函数,是创建变量时使用的一个特殊的方法,与类名同名。关于它的具体介绍会在之后的篇章里做说明,这里就不详细介绍了。

对象