|
面向对象的编程概念
如果您以前从未使用过面向对象的编程语言,则需要学习一些基本概念,然后才能开始编写任何代码。本课将向您介绍对象,类,继承,接口和包。每个讨论都集中在这些概念如何与现实世界相关的同时,同时提供对Java编程语言语法的介绍。
什么是对象?
对象是具有相关状态和行为的软件包。软件对象通常用于建模您在日常生活中发现的现实世界对象。本课说明了对象中状态和行为的表示方式,介绍了数据封装的概念,并说明了以这种方式设计软件的好处。
对象是理解[i,面向对象[/i,技术的关键。现在环顾四周,您会发现许多现实世界中的物体示例:您的狗,您的书桌,电视机,您的自行车。
现实世界中的对象共有两个特征:它们都具有[i,状态[/i,和[i,行为[/i,。狗具有状态(名称,颜色,品种,饥饿)和行为(吠叫,抓捕,摇尾巴)。自行车还具有状态(当前档位,当前踏板节奏,当前速度)和行为(换档,改变踏板节奏,施加制动)。识别现实世界对象的状态和行为是从面向对象程序设计开始思考的一种好方法。
现在花一分钟时间观察您附近区域中的真实对象。对于您看到的每个对象,问自己两个问题:“该对象可能处于什么状态?” 和“此对象可能执行什么行为?”。确保写下您的观察结果。在执行操作时,您会注意到现实世界中对象的复杂性各不相同。您的台式机灯可能只有两种可能的状态(打开和关闭)和两种可能的行为(打开,关闭),但是台式机收音机可能具有其他状态(打开,关闭,当前音量,当前电台)和行为(打开) ,请关闭,增大音量,减小音量,进行搜索,扫描和调整)。您可能还会注意到,某些对象又将包含其他对象。这些真实的观察结果都转化为面向对象编程的世界。
一个软件对象。
软件对象在概念上与现实世界中的对象相似:它们也由状态和相关行为组成。对象将其状态存储在[i,字段中[/i,(某些编程语言中的变量),并通过[i,方法[/i,(某些编程语言中的函数)公开其行为。方法在对象的内部状态上运行,并用作对象间通信的主要机制。隐藏内部状态并要求通过对象的方法执行所有交互被称为[i,数据封装[/i,-面向对象编程的基本原理。
考虑一辆自行车,例如:
建模为软件对象的自行车。
通过分配状态(当前速度,当前踏板踏频和当前档位)并提供更改该状态的方法,对象可以控制外部环境的使用方式。例如,如果自行车仅具有6个齿轮,则更改齿轮的方法可能会拒绝小于1或大于6的任何值。
将代码捆绑到单个软件对象中可带来许多好处,包括:
[list=1,
[*,模块化:可以独立于其他对象的源代码编写和维护对象的源代码。创建对象后,可以轻松地在系统内部传递对象。
[*,信息隐藏:通过仅与对象的方法进行交互,其内部实现的细节仍对外界隐藏。
[*,代码重用:如果某个对象已经存在(也许由其他软件开发人员编写),则可以在程序中使用该对象。这使专家可以实现/测试/调试特定于任务的复杂对象,然后您可以信任它们以自己的代码运行。
[*,可插拔性和调试简便性:如果发现某个特定对象有问题,则只需将其从应用程序中删除,然后插入另一个对象作为替换对象即可。这类似于解决现实世界中的机械问题。如果螺栓断裂,更换[i,它[/i,,而不是整个机器。
[/list,什么是类?
类是从中创建对象的蓝图或原型。本节定义了一个模型,用于对实际对象的状态和行为进行建模。它特意侧重于基础知识,展示了即使是一个简单的类也如何能够清晰地对状态和行为进行建模。
在现实世界中,您经常会发现许多同一种个体。可能还有成千上万的其他自行车,都具有相同的品牌和型号。每辆自行车都是根据相同的设计图制造的,因此包含相同的组件。用面向对象的术语来说,我们说您的自行车是称为自行车的一[i,类对象[/i,的[i,实例[/i,。一[i,类[/i,是从中创建单个对象的蓝图。
以下 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方法。那是因为它不是一个完整的应用程序。它只是应用程序中可能[i,使用的[/i,自行车的蓝图。创建和使用新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编程语言提供的简单语法从另一个类派生一个类。
不同种类的对象通常彼此之间有一定数量的共同点。例如,山地车,公路车和双人自行车都具有自行车的特征(当前速度,当前踏板节奏,当前档位)。然而,每个自行车还定义了使其与众不同的其他功能:双人自行车有两个座位和两组车把;公路自行车有下降的车把;一些山地自行车有一个附加的链环,使它们的齿轮比更低。
面向对象的编程允许类从其他类[i,继承[/i,常用的状态和行为。在这个例子中,Bicycle现在变成了[i,父[/i,的MountainBike,RoadBike和TandemBike。在Java编程语言中,每个类都可以具有一个直接的超类,并且每个超类都具有无限数量的[i,子[/i,类的潜力:
自行车课程的层次结构。
创建子类的语法很简单。在类声明的开头,使用extends关键字,后跟要从其继承的类的名称:
class MountainBike extends Bicycle {
// new fields and methods defining
// a mountain bike would go here
}
它提供MountainBike了与相同的所有字段和方法Bicycle,但允许其代码仅专注于使其独特的功能。这使子类的代码易于阅读。但是,您必须注意正确记录每个超类定义的状态和行为,因为该代码不会出现在每个子类的源文件中。
什么是接口?
接口是类与外界之间的契约。当一个类实现一个接口时,它承诺提供该接口发布的行为。本节定义了一个简单的接口,并说明了实现该接口的任何类的必要更改。
正如您已经了解的那样,对象通过它们公开的方法定义了它们与外界的交互。方法形成对象与外界的[i,接口[/i,;例如,电视机正面的按钮是您与塑料外壳另一侧的电线之间的接口。您按下“电源”按钮可以打开和关闭电视。
在最常见的形式中,接口是一组具有空主体的相关方法。如果将自行车的行为指定为接口,则可能如下所示:
interface Bicycle {
// wheel revolutions per minute
void changeCadence(int newValue);
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
要实现此接口,您的类的名称将更改(例如,更改为特定品牌的自行车,例如ACMEBicycle),并且您可以implements在类声明中使用关键字:
class ACMEBicycle implements Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
// The compiler will now require that methods
// changeCadence, changeGear, speedUp] and applyBrakes
// all be implemented. Compilation will fail if those
// methods are missing from this class.
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)。
包是组织一组相关类和接口的名称空间。从概念上讲,您可以将软件包视为类似于计算机上的不同文件夹。您可以将HTML页面保留在一个文件夹中,将图像保留在另一个文件夹中,并将脚本或应用程序保留在另一个文件夹中。因为用Java编程语言编写的软件可以由成百上千[i,个[/i,单独的类组成,所以通过将相关的类和接口放入包中来使事情井井有条是很有意义的。
Java平台提供了适合在您自己的应用程序中使用的庞大的类库(一组软件包)。该库称为“应用程序编程接口”或简称“ API”。它的程序包代表与通用编程最常关联的任务。例如,一个String对象包含字符串的状态和行为。一个File对象使程序员可以轻松地创建,删除,检查,比较或修改文件系统上的文件;一种Socket对象允许创建和使用网络套接字;各种GUI对象控制按钮和复选框,以及与图形用户界面有关的其他任何内容。从字面上看,有数千种课程可供选择。程序员,这使您可以专注于特定应用程序的设计,而不是使其工作所需的基础结构。
问题与练习:面向对象的编程概念
使用本节中提出的问题和练习来测试您对对象,类,继承,接口和包的理解
问题
[list=1,
[*,实际对象包含___和___。
[*,软件对象的状态存储在___中。
[*,软件对象的行为通过___公开。
[*,隐藏来自外部世界的内部数据,并仅通过公开的方法访问它,称为数据___。
[*,软件对象的蓝图称为___。
[*,常见行为可以在___中定义,并可以使用___关键字继承到___中。
[*,没有实现的方法的集合称为___。
[*,通过功能组织类和接口的名称空间称为___。
[*,术语API代表___?
[/list,练习题
[list=1,
[*,为您在本教程开始时观察到的每个实际对象创建新类。如果您忘记了必需的语法,请参考Bicycle类。
[*,对于上面创建的每个新类,创建一个定义其行为的接口,然后要求您的类实现它。省略一种或两种方法,然后尝试编译。错误是什么样的?
[/list, |
|