Java基础教程(4)--面向对象概念
如果你之前从来没有使用过面向对象编程语言,那么在学习Java之前需要先理解几个有关面向对象编程的基本概念。这篇教程将会向你介绍对象、类、集成、接口和包的概念,以及这些概念是如何与现实世界相关联,并介绍这些概念在Java语言中的体现。
一.对象
对象将状态和行为绑定在一起,它可以被用来模拟你能列举出的现实世界中的任何实体。这一小节将会解释如何在对象中表示状态和行为,介绍封装的概念,并解释这种软件设计方式的好处。
对象是理解面向对象技术的关键。环顾四周,你会发现许多现实世界中的对象:狗、桌子、电视机、自行车等。现实世界中的对象都有两个特征:它们都有状态和行为。狗有自己的状态(名字、颜色、品种、是否饥饿等)和行为(叫、跑、吃等)。自行车也有状态(当前齿轮、当前转速和当前速度等)和行为(换挡、变速和刹车等)。识别现实对象的状态和行为是开始使用面向对象编程概念的好方法。
现在花点时间来观察附近的真实物体。对于看到的每个对象,请问自己两个问题:这个对象可能存在哪些状态?这个对象可以执行哪些行为?你会注意到现实世界中的物体的复杂程度各不相同。桌面上的台灯可能只有两种状态(开和关)和两种可能的行为(打开和关闭),但电视可能有更多的状态(开,关,当前音量,当前电台)和更多的行为(打开,关闭,调大音量,调小音量,搜索等)。你可能还会注意到,某些对象也会包含其他对象。
编程中的对象在概念上类似于现实世界的对象:它们也包括状态和行为。对象将其状态存储在域(编程语言中的变量)中,并通过方法(编程语言中的函数)公开其行为。方法对对象的内部状态进行操作,并作为对象和对象通信的主要机制。隐藏内部状态并要求通过对象的方法执行所有交互称为封装,这正是面向对象编程的基本原则。
即使对象向外界提供了改变其状态的方法,它仍然控制着外界如何来使用这些方法。例如,如果自行车只有6个齿轮,换档的方法可以拒绝任何小于1或大于6的值。
将代码与对象绑定有许多好处,包括:
- 模块化:对象的源代码可以独立于其他对象的源代码进行编写和维护。一旦创建,对象就可以很容易地在系统内部传递。
- 信息隐藏:尽管对象通过方法与外界交互,但其内部实现的细节仍然对外界隐藏。
- 代码重用:如果一个对象已经存在(可能由另一个软件开发人员编写),那么你可以在程序中使用该对象。
- 可插拔和便于调试:如果某个特定对象出现问题,你可以简单地将其从应用程序中删除,并插入另一个对象作为替换对象。这类似于解决现实世界中的机械问题。如果螺丝坏了,你就换掉它,而不是整台机器。
二.类
类是创建对象的蓝图或原型。本节定义了一个模拟现实世界对象的状态和行为的类。我将利用它来展示一个简单的类如何能够模拟状态和行为。
在现实世界中,经常会发现许多相同类型的对象。可能存在数千辆自行车,它们都具有相同的品牌和型号。每辆自行车都是使用相同的原型构建的,因此包含相同的组件。在面向对象的术语中,我们将每辆自行车称为自行车类的一个实例。
下面的Bicycle类是自行车的一种实现方式:
class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" + cadence + " speed:" + speed + " gear:" + gear);
}
}
你可能对Java的语法还不了解,但是这个类的定义是基于我们之前讨论的自行车对象的。cadence,speed和gear域表示了对象的状态,changeCadence,changeGear,speedUp等方法定义了对象与外界的联系。
你可能已经注意到Bicycle类不包含main方法,这是因为它不是一个完整的应用程序。它只是可能在应用程序中使用到的自行车的原型。创建和使用新Bicycle对象的责任属于应用程序中的其他类。
下面的BicycleDemo类创造了两个Bicycle对象并调用了它们的方法:
class BicycleDemo {
public static void main(String[] args) {
// Create two different Bicycle objects
Bicycle bike1 = new Bicycle();
Bicycle bike2 = new Bicycle();
// Invoke methods on those objects
bike1.changeCadence(50);
bike1.speedUp(10);
bike1.changeGear(2);
bike1.printStates();
bike2.changeCadence(50);
bike2.speedUp(10);
bike2.changeGear(2);
bike2.changeCadence(40);
bike2.speedUp(10);
bike2.changeGear(3);
bike2.printStates();
}
}
这个样例的输出打印了两辆自行车最终的转速,速度和档位:
cadence:50 speed:10 gear:2
cadence:40 speed:20 gear:3
三.继承
继承为组织和构建软件提供了强大而自然的机制。本节介绍了类如何从超类继承状态和行为,并解释了如何使用Java语言提供的语法从一个类派生出另一个类。
有些不同种类的物体具备某些相同的特性。例如,公路自行车和双人自行车都具有自行车的特性(速度,转速和档位)。然而,每种自行车还具有与众不同的其他功能:双人自行车有两个座位和两套车把,公路自行车有把手。
面向对象编程允许类从其他类继承通用的状态和行为。在这个例子中,Bicycle变成了RoadBike和TandemBike的超类。在Java编程语言中,允许每个类具有一个直接超类,并且每个超类都有可能存在无限数量的子类。
定义子类的语法很简单。在你要定义的类名后面使用extends关键字,再跟上要继承的类的名字:
class MountainBike extends Bicycle {
// new fields and methods defining a mountain bike would go here
}
MountainBike具有和Bicycle相同的域和方法,并且允许其代码专注于独特的功能,这使得子类的代码易于阅读。但是,必须注意正确记录每个超类定义的状态和行为,因为该代码不会出现在每个子类的源文件中。
四.接口
接口是类与外部世界之间的契约。当类实现接口时,它承诺提供由该接口发布的行为。本节定义了一个简单的接口,并解释了任何实现了它的类所需要做的必要的更改。
正如之前了解的那样,对象通过它们公开的方法来进行与外部世界的交互。方法形成对象与外界的接口。例如,电视机正面的按钮是你与塑料外壳内的电线之间的接口,你可以使用电源键来打开和关闭电视。
在最常见的形式中,接口是一组没有方法体的方法。自行车的行为(如果指定为接口)可能如下所示:
interface Bicycle {
void changeCadence(int newValue);
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
要实现这个接口,在你要定义的类名后面使用implements关键字,再跟上要实现的接口的名字:
class ACMEBicycle implements Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" + cadence + " speed:" + speed + " gear:" + gear);
}
}
实现接口就相当于类在履行和接口的承诺。接口形成了类和外部世界之间的契约,而这个契约在编译时由编译器进行检测。如果类声称要实现一个接口,那么该类必须提供接口定义的所有方法,然后该类才能成功编译。
五.包
包是用于以逻辑方式组织类和接口的命名空间。将代码放入包中可以使大型软件项目更易于管理。本节解释了这样做的原因,并向您介绍Java平台提供的应用程序编程接口(API)。
包是一个命名空间,用于组织一组相关的类和接口。从概念上讲,可以将包视为与计算机上的文件夹。因为用Java编程语言编写的应用可能由数百或数千个单独的类组成,所以通过将相关的类和接口放入包中来组织应用的结构是很有意义的。
Java平台提供了一个很大的类库(一组包),该库称为“应用程序编程接口”,简称“API”。它代表了最常用于通用编程的任务。例如,String对象包含字符串的状态和行为; 一个File对象允许程序员轻松地创建、删除、检查、比较或修改文件系统上的文件; 一个Socketobject允许创建和使用网络套接字。有数以千计的类可供选择。这使程序员可以专注于特定应用程序的设计,而不是设计其工作所需的基础结构。
在Java Platform API Specification中包含了所有的包,接口,类的完整列表。作为程序员,它将成为最重要的参考文档。