对象:特征
本节课将介绍对象的两个基本特征:状态和行为。
状态与行为
要理解面向对象编程技术,我们首先需要了解对象。在编程世界中,我们复现了现实世界中物体的行为和状态。环顾四周,我们可以看到人类、狗、电脑、汽车等许多现实中的物体在我们身边移动。
深入观察会让我们对对象有更深刻的理解。我们发现,现实世界中的物体都具有两个特征:它们都有状态和行为。人类有不同的状态,比如姓名、身高、情绪等;同时也有各种行为,如喊叫、行走、奔跑等。
我们相信每个对象都有其自身的复杂性,并且各不相同。一开始,我们只需要知道对象与类之间存在关系。要创建一个对象,我们需要将它的状态和行为写入一个类中。你可以把这看作是一个蓝图。
编码示例:6
在这个例子中,我们将处理一个对象——一辆汽车。为了简化,我们只保留两个状态:gear(档位)和 speed(速度)。当档位升高时,速度增加,反之亦然。这些是对象的行为,也是其动作部分。由于我们赋予了状态(当前的速度或档位),也可以称它们为对象的属性。当我们改变状态或属性时,需要提供一些方法。因此,一辆汽车有一个名为 speed 的状态,还有一个名为 speedUp 的方法来改变当前速度。
因此,在一个类中,我们需要分别设计并编写这些内容。在某些情况下,我们需要整数;在其他情况下,可能需要带小数点的数值。在很多场景下,我们还需要文本,而文本本质上是一串字符。这也是为什么在简要介绍面向对象编程之后,我们会讨论基本数据类型,如整数、浮点数等。
首先,我们需要编写一个 Car 类。然后,在 main() 方法中创建一辆汽车对象。
1class Car { 2 int speed = 0; 3 int gear = 1; 4 void changeGear(int newValue) { 5 gear = newValue; 6 } 7 void speedUp(int increment) { 8 speed = speed + increment; 9 } 10 void speedDown(int decrement) { 11 speed = speed - decrement; 12 } 13 void stateOfCar() { 14 System.out.println(" 汽车的速度:" + speed + ",当前档位:" + gear); 15 } 16} 17 18public class ExampleSix { 19 public static void main(String args[]){ 20 // 创建一辆汽车对象 21 Car car1 = new Car(); 22 car1.changeGear(2); 23 car1.speedUp(10); 24 car1.stateOfCar(); 25 car1.changeGear(3); 26 car1.speedUp(30); 27 car1.stateOfCar(); 28 car1.changeGear(1); 29 car1.speedDown(35); 30 car1.stateOfCar(); 31 } 32}
代码说明
阅读代码有助于理解我们在 Car 类中如何声明状态,以及如何通过提供方法来改变这些状态。我们使用 new 关键字仅创建了一个汽车对象。
编码示例:7
在这个例子中,我们引入了另一辆汽车对象,同时添加了一个新的方法来让汽车停止。
1class AnotherCar { 2 3 int speed = 0; 4 int gear = 0; 5 6 void changeGear(int newValue) { 7 gear = newValue; 8 } 9 10 void speedUp(int increasing) { 11 speed = speed + increasing; 12 } 13 14 void speedDown(int reducing) { 15 speed = speed - reducing; 16 } 17 18 void stopCar(int noSpeed){ 19 speed = speed * noSpeed; 20 } 21 22 void stateOfCar() { 23 System.out.println(" 汽车的速度:" + speed + ",当前档位:" + gear); 24 } 25} 26 27public class ExampleSeven { 28 public static void main(String args[]){ 29 // 创建两个汽车对象 30 AnotherCar car1 = new AnotherCar(); 31 AnotherCar car2 = new AnotherCar(); 32 car1.changeGear(2); 33 car1.speedUp(10); 34 car1.stateOfCar(); 35 car1.changeGear(3); 36 car1.speedUp(30); 37 car1.stateOfCar(); 38 car1.changeGear(1); 39 car1.speedDown(35); 40 car1.stateOfCar(); 41 car2.changeGear(2); 42 car2.speedUp(20); 43 car2.stateOfCar(); 44 car2.changeGear(1); 45 car2.stopCar(0); 46 car2.stateOfCar(); 47 } 48}
代码说明
如上所示,我们创建了两个汽车对象。我们还添加了一个新方法 stopCar,用于将速度值变为 0(第 45 行)。
我们已经了解了一些关于对象的知识。当我们创建一个对象时,代码如下:
1AnotherCar car1 = new AnotherCar();
继承
你可能注意到 AnotherCar 类中没有 main() 方法。这是因为它是汽车对象的一个蓝图,而不是一个完整的应用程序。我们将在包含 main() 方法的应用程序类中使用这个蓝图或类。应用程序类负责创建对象。这一点在上面的代码(示例 7)中已经体现。
我们使用 new 关键字创建了一个具有蓝图支撑的新对象。在这个蓝图或类中,我们指定了它应具有的状态类型。我们也定义了用于改变这些状态的方法。
汽车对象的名称最终是 car1,但它也可以命名为 'jaguar'。无论使用什么名称,都要注意上下文。名称应当具有意义且表达清晰,以便日后阅读代码时能够理解。这里的名称 car1 也被称为引用变量,它存储在“栈”内存中。然而,新创建的汽车对象则存储在内存的“堆”区域。这个存储在“栈”中的引用变量 car1 指向“堆”中新建的对象。我们将在第四章中通过大量示例详细讨论这一主题,届时将对比不同类型的变量以及用于描述对象“状态”的数据类型的特性。
面向对象编程具有以下优点:
- 具有模块化特性,
- 对象的源代码可以独立编写和维护,
- 一旦创建,对象可以被系统传递使用。
信息隐藏
第二点重要的是信息隐藏,即外部世界不知道内部发生了什么。内部实现细节被隐藏起来。
一个对象可能拥有巨大的能力。它内部可能包含成千上万个其他对象。这意味着开发者创建的对象可以被其他开发者重复使用。代码复用是另一个优势。
如果某个对象出现问题,我们可以用另一个对象替换它。例如,当门把手无法正常工作时,我们更换把手,而不是更换整扇门。
我们将在后续章节中详细讨论这些特性。在此之前,我们需要先学习基本数据类型和非基本数据类型,因为它们是创建对象所必需的基础知识。