科技文章翻译
郑州大学科技文章翻译
题 目: Introduction to Objects 指导教师: 周清雷 职称: 教授
学生姓名: 郭利军 学号: [1**********]
专 业: 计算机科学与技术 院(系): 信息工程学院 完成时间: 2007-6-3
年 月 日
Introduction to Objects
“We cut nature up, organize it into concepts, and ascribe significances as we do, largely because we are parties to an agreement that holds throughout our speech community and is codified in the patterns of our language ... we cannot talk at all except by subscribing to the organization and classification of data which the agreement decrees.” Benjamin Lee Whorf (1897-1941)
The genesis of the computer revolution was in a machine. The genesis of our programming languages thus tends to look like that machine.
But computers are not so much machines as they are mind amplification tools (“bicycles for the mind,” as Steve Jobs is fond of saying) and a different kind of expressive medium. As a result, the tools are beginning to look less like machines and more like parts of our minds, and also like other forms of expression such as writing, painting, sculpture, animation, and filmmaking. Object-oriented programming (OOP) is part of this movement toward using the computer as an expressive medium.
This chapter will introduce you to the basic concepts of OOP, including an overview of development methods. This chapter, and this book, assume that you have had experience in a procedural programming language, although not necessarily C. If you think you need more preparation in programming and the syntax of C before tackling this book, you should work through the Foundations for Java training CD ROM, bound in the back of this book. This chapter is background and supplementary material. Many people do not feel comfortable wading into object-oriented programming without
understanding the big picture first. Thus, there are many concepts that are introduced here to give you a solid overview of OOP. However, other people may not get the big picture concepts until they’ve seen some of the mechanics first; these people may become bogged down and lost without some code to get their hands on. If you’re part of this latter group and are eager to get to the specifics of the language, feel free to jump past this chapter—skipping it at this point will not prevent you from writing programs or learning the language. However, you will want to come back here eventually to fill in your knowledge so you can understand why objects are important and how to design with them.
The progress of abstraction
All programming languages provide abstractions. It can be argued that the complexity of the problems you’re able to solve is directly related to the kind
and quality of abstraction. By “kind” I mean, “What is it that you are abstracting?” Assembly language is a small abstraction of the underlying machine. Many so-called “imperative” languages that followed (such as FORTRAN, BASIC, and C) were abstractions of assembly language. These languages are big improvements over assembly language, but their primary abstraction still requires you to think in terms of the structure of the computer rather than the structure of the problem you are trying to solve. The
programmer must establish the association between the machine model (in the “solution space,” which is the place where you’re modeling that problem, such as a computer) and the model of the problem that is actually being solved (in the “problem space,” which is the place where the problem exists). The effort required to perform this mapping, and the fact that it is extrinsic to the programming language, produces programs that are difficult to write and expensive to maintain, and as a side effect created the entire “programming methods” industry.
The alternative to modeling the machine is to model the problem you’re trying to solve. Early languages such as LISP and APL chose particular views of the world (“All problems are ultimately lists” or “All problems are algorithmic,” respectively). PROLOG casts all problems into chains of decisions. Languages have been created for constraint-based programming and for programming exclusively by manipulating graphical symbols. (The latter proved to be too restrictive.) Each of these approaches is a good solution to the particular class of problem they’re designed to solve, but when you step outside of that domain they become awkward.
The object-oriented approach goes a step further by providing tools for the programmer to represent elements in the problem space. This representation is general enough that the programmer is not constrained to any particular type of problem. We refer to the elements in the problem space and their representations in the solution space as “objects.” (You will also need other objects that don’t have problem-space analogs.) The idea is that the program is allowed to adapt itself to the lingo of the problem by adding new types of objects, so when you read the code describing the solution, you’re reading words that also express the problem. This is a more flexible and powerful language abstraction than what we’ve had before.Thus, OOP allows you to describe the problem in terms of the problem, rather than in terms of the computer where the solution will run. There’s still a connection back to the computer: each object looks quite a bit like a little computer—it has a state, and it has operations that you can ask it to perform. However, this doesn’t seem like such a bad analogy to objects in the real world—they all have characteristics and behaviors.
Alan Kay summarized five basic characteristics of Smalltalk, the first
successful object-oriented language and one of the languages upon which Java
is based. These characteristics represent a pure approach to object-oriented programming:
1. Everything is an object. Think of an object as a fancy variable; it stores data, but you can “make requests” to that object, asking it to
perform operations on itself. In theory, you can take any conceptual
component in the problem you’re trying to solve (dogs, buildings,
services, etc.) and represent it as an object in your program.
2. A program is a bunch of objects telling each other what to do by sending messages. To make a request of an object, you “send a message” to that object. More concretely, you can think of a message as a request to call a method that belongs to a particular object.
3. Each object has its own memory made up of other objects. Put another way, you create a new kind of object by making a package
containing existing objects. Thus, you can build complexity into a
program while hiding it behind the simplicity of objects.
4. Every object has a type. Using the parlance, each object is an
instance of a class, in which “class” is synonymous with “type.” The
most important distinguishing characteristic of a class is “What
messages can you send to it?”
5. All objects of a particular type can receive the same messages. This is actually a loaded statement, as you will see later. Because an
object of type “circle” is also an object of type “shape,” a circle is
guaranteed to accept shape messages. This means you can write code that talks to shapes and automatically handle anything that fits the
description of a shape. This substitutability is one of the powerful
concepts in OOP.
Booch offers an even more succinct description of an object:
An object has state, behavior and identity.
This means that an object can have internal data (which gives it state),
methods (to produce behavior), and each object can be uniquely distinguished from every other object—to put this in a concrete sense, each object has a unique address in memory.
An object has an interface
Aristotle was probably the first to begin a careful study of the concept of type; he spoke of “the class of fishes and the class of birds.” The idea that all objects, while being unique, are also part of a class of objects that have characteristics and behaviors in common was used directly in the first object-oriented
language, Simula-67, with its fundamental keyword class that introduces a new type into a program.
Simula, as its name implies, was created for developing simulations such as the classic “bank teller problem.” In this, you have a bunch of tellers,
customers, accounts, transactions, and units of money—a lot of “objects.” Objects that are identical except for their state during a program’s execution are grouped together into “classes of objects” and that’s where the keyword class came from. Creating abstract data types (classes) is a fundamental concept in object-oriented programming. Abstract data types work almost exactly like built-in types: You can create variables of a type (called objects or instances in object-oriented parlance) and manipulate those variables (called sending messages or requests; you send a message and the object figures out what to do with it). The members (elements) of each class share some
commonality: every account has a balance, every teller can accept a deposit, etc. At the same time, each member has its own state: each account has a different balance, each teller has a name. Thus, the tellers, customers,
accounts, transactions, etc., can each be represented with a unique entity in the computer program. This entity is the object, and each object belongs to a particular class that defines its characteristics and behaviors.
So, although what we really do in object-oriented programming is create new data types, virtually all object-oriented programming languages use the “class” keyword. When you see the word “type” think “class” and vice versa.
Since a class describes a set of objects that have identical characteristics (data elements) and behaviors (functionality), a class is really a data type because a floating point number, for example, also has a set of characteristics and
behaviors. The difference is that a programmer defines a class to fit a problem rather than being forced to use an existing data type that was designed to represent a unit of storage in a machine. You extend the programming
language by adding new data types specific to your needs. The programming system welcomes the new classes and gives them all the care and
type-checking that it gives to built-in types.
The object-oriented approach is not limited to building simulations. Whether or not you agree that any program is a simulation of the system you’re
designing, the use of OOP techniques can easily reduce a large set of problems to a simple solution.
Once a class is established, you can make as many objects of that class as you like, and then manipulate those objects as if they are the elements that exist in the problem you are trying to solve. Indeed, one of the challenges of
object-oriented programming is to create a one-to-one mapping between the elements in the problem space and objects in the solution space.
But how do you get an object to do useful work for you? There must be a way to make a request of the object so that it will do something, such as complete a transaction, draw something on the screen, or turn on a switch. And each object can satisfy only certain requests. The requests you can make of an object are defined by its interface, and the type is what determines the interface. A simple example might be a representation of a light bulb:
Light lt = new Light();
lt.on();
The interface establishes what requests you can make for a particular object. However, there must be code somewhere to satisfy that request. This, along with the hidden data, comprises the implementation. From a procedural programming standpoint, it’s not that complicated. A type has a method
associated with each possible request, and when you make a particular request to an object, that method is called. This process is usually summarized by
saying that you “send a message” (make a request) to an object, and the object figures out what to do with that message (it executes code).
Here, the name of the type/class is Light, the name of this particular Light object is lt, and the requests that you can make of a Light object are to turn it on, turn it off, make it brighter, or make it dimmer. You create a Light object by defining a “reference” (lt) for that object and calling new to request a new object of that type. To send a message to the object, you state the name of the object and connect it to the message request with a period (dot). From the standpoint of the user of a predefined class, that’s pretty much all there is to programming with objects.
The preceding diagram follows the format of the Unified Modeling Language (UML). Each class is represented by a box, with the type name in the top portion of the box, any data members that you care to describe in the middle portion of the box, and the methods (the functions that belong to this object, which receive any messages you send to that object) in the bottom portion of
the box. Often, only the name of the class and the public methods are shown in UML design diagrams, so the middle portion is not shown. If you’re
interested only in the class name, then the bottom portion doesn’t need to be shown, either.
An object provides services
While you’re trying to develop or understand a program design, one of the best ways to think about objects is as “service providers.” Your program itself will provide services to the user, and it will accomplish this by using the services offered by other objects. Your goal is to produce (or even better,
locate in existing code libraries) a set of objects that provide the ideal services to solve your problem.
A way to start doing this is to ask “if I could magically pull them out of a hat, what objects would solve my problem right away?” For example, suppose you are creating a bookkeeping program. You might imagine some objects that contain pre-defined bookkeeping input screens, another set of objects that perform bookkeeping calculations, and an object that handles printing of checks and invoices on all different kinds of printers. Maybe some of these objects already exist, and for the ones that don’t, what would they look like? What services would those objects provide, and what objects would they need to fulfill their obligations? If you keep doing this, you will eventually reach a point where you can say either “that object seems simple enough to sit down and write” or “I’m sure that object must exist already.” This is a reasonable way to decompose a problem into a set of objects.
Thinking of an object as a service provider has an additional benefit: it helps to improve the cohesiveness of the object. High cohesion is a fundamental quality of software design: It means that the various aspects of a software component (such as an object, although this could also apply to a method or a library of objects) “fit together” well. One problem people have when
designing objects is cramming too much functionality into one object. For example, in your check printing module, you may decide you need an object that knows all about formatting and printing. You’ll probably discover that this is too much for one object, and that what you need is three or more
objects. One object might be a catalog of all the possible check layouts, which can be queried for information about how to print a check. One object or set of objects could be a generic printing interface that knows all about different kinds of printers (but nothing about bookkeeping—this one is a candidate for buying rather than writing yourself). And a third object could use the services of the other two to accomplish the task. Thus, each object has a cohesive set of services it offers. In a good object-oriented design, each object does one thing well, but doesn’t try to do too much. As seen here, this not only allows the
discovery of objects that might be purchased (the printer interface object), but it also produces the possibility of an object that might be reused somewhere else (the catalog of check layouts).
Treating objects as service providers is a great simplifying tool, and it’s very useful not only during the design process, but also when someone else is
trying to understand your code or reuse an object—if they can see the value of the object based on what service it provides, it makes it much easier to fit it into the design.
The hidden implementation
It is helpful to break up the playing field into class creators (those who create new data types) and client programmers(the class consumers who use the data types in their applications). The goal of the client programmer is to collect a toolbox full of classes to use for rapid application development. The goal of the class creator is to build a class that exposes only what’s necessary to the client programmer and keeps everything else hidden. Why? Because if it’s hidden, the client programmer can’t access it, which means that the class creator can change the hidden portion at will without worrying about the impact on anyone else. The hidden portion usually represents the tender
insides of an object that could easily be corrupted by a careless or uninformed client programmer, so hiding the implementation reduces program bugs. The concept of implementation hiding cannot be overemphasized. In any
relationship it’s important to have boundaries that are respected by all parties involved. When you create a library, you establish a relationship with the
client programmer, who is also a programmer, but one who is putting together an application by using your library, possibly to build a bigger library. If all the members of a class are available to everyone, then the client programmer can do anything with that class and there’s no way to enforce rules. Even though you might really prefer that the client programmer not directly manipulate some of the members of your class, without access control there’s no way to prevent it. Everything’s naked to the world.
对象介绍
“我们分解自然界,组织它成为概念,并且当我们做时,总结重要性,很大程度上是因为我们知道我们的语言社区所共同持有的,并以我们的语言的形式所固定下来的一种约定…我们根本无法交谈除非遵守这个约定中有关数据的组织和分类的内容.” Benjamin Lee Whorf(1897-1941)
计算机革命起源于机器,因此我们编程语言的发展也始于机器.
但是计算机不象机器那么简单,计算机是思维扩展工具(“思维的自行车”,Steve Job 喜欢说的)和不同类型的表达方法.结果,计算机开始看起来越来越不象机器而更象我们思维的一部分,而且象其他的表达形式, 比如写作、绘画、雕刻、动画、电影等.面向对象编程(OOP)就是以计算机为表达媒介的一种.
本章将介绍OOP的基本概念,包括开发方法的概述.本章以至本书都假定你有一定编程的经验,并不一定要是C放言. 如果你认为你在阅读本书之前还需要在编程以及C语法方面多做些准备,您可以看下本书所附的培训光盘“Java基础(Foundations for Java)”。 本章是背景和补充材料.在没有了解全貌这前,许多人感觉无法轻松从事面向对象编程.因此,这里给出了许多概念以给你一个OOP的大观.然而,许多人可能无法理解概念直到看到一些实例;那些人可能如果没有看到一些代码就可能迷失方向.如果你就是这样,而且渴望得到这门语言的细节,那么可以跳过本章——此处跳过本章不会影响你写程序或学习语言.然而您最终还是会回到本章来填补您的知识,这样您才能够了解到为什么对象如此重要,以及怎样使用对象来进行设计。
抽象过程
所有的编程语言都提供抽象概念.可以认为你要解决问题的复杂性与抽象机制的类型和质量有关.但是我说的类型”是指”你抽象的是什么?” 汇编语言是对底层机器的小型抽象.许多所谓的”命令语言” (比如FORTRAN、BASIC、C等)都是对汇编语言的抽象。这些语言在汇编语言之上有了大幅的改进,但是他们主要的抽象仍然需要你考虑计算机的结构而不是你要解决的问题的结构. 程序员必须建立在机器模型(位于你对问题建模所在的解空间内,例如计算机)和实际待解问题模型(位于问题所在的问题空间)内)之间的关联. 建立这种映射是费力的,而且它不属于编程语言的内在性质,这使得程序难以编写,并且维护代价高昂。由此,产生了完整的“编程方法”产业。
另一种方法对机器建模是对你要解决的问题的建模.早期语言比如LISP,APL,选择世界的某种特定视图分别(对应于“所有问题最终都是列表”或者“所有问题都是算法形式的”)。PROLOG则将所有问题都转换成为决策链(Chain of decisions)。此外还产生了基于约束条件(constraint-based)编程的语言和专门通过对图形符号操作来实现编程的语言(后者被证明限制性过强)。这些方式对于它们被设计时所要解决的特定类型的问题都是不错的解决方案,但是一旦超出其特定领域,它们就不行了。
面向对象方法通过向程序员提供在问题空间中代替元素的工具而领先一步. 这种表示方式具有足够的概括性,使得程序员不会受限于任何特定类型的问题。我们把问题空间中的元素和他们在解决空间中的表示方法叫做”对象”.(你还需要其它没有解决空间的对象) 这种思想的实质是:程序可以通过添加新类型的对象使自身适用于某个特定问题。因此,当你在阅读描述解决方案的代码的同时,也是在阅读问题的表述。相比以前我们所拥有的所有语言,这是一种更灵活和更强有力的语言抽象。所以,OOP允许以问题的形式来描述问题,而不
是以执行解决方案的计算机的形式来描述问题。它仍然与计算机有联系:每个对象看起来都象是一个小计算机——它具有状态,并且能够执行你赋予它的各种操作。如果要在现实世界中对对象作类比,那么说它们都具有特性(Characteristic)和行为(Behavior)似乎不错。
Alan Kay曾经总结了第一个成功的面向对象语言,同时也是Java赖为根基的语言之一的Smalltalk的五个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式:
1. 一切都是对象.把对象看成新奇的变量;它可以存储数据,此外,它还可在自身上执
行.理论上, 你可以抽取待解问题的任何概念化构件(狗、建筑物、服务等),将
其表示为程序中的对象。
2. 程序是很多对象,彼此发消息相互调用.为调用另一个对象,你发”信息”给那个
对象.更具体点,你可以把消息看作是调用属于一个特定对象的方法.
3. 每个对象都拥有由其它对象所构成的存储。你可以通过创建包含现有对象集合的
包的方式来创建新类型的对象。因此,你可以在程序中构建复杂的体系,同时将
其复杂性通过对象的质朴性得以屏蔽。
4. 每个对象都有类型.用这个说法,第个对象都是一个类的实例,类是与类型同意.类
的最大的不同是”你能发给他什么信息?”
5. 某一特定类型的所有对象都可以接收(Receive)同样的消息。这是一句意味深长的
表述,你在稍后便会看到。因为“圆形(circle)”类型的对象同时也是“几何形
(shape)”类型的对象,所以一个“圆形”对象必定能够接受(accept)发送给“几
何形”对象的消息。这意味着你可以编写与“几何形”交互并自动处理所有与几何
形性质相关的事物的的代码。这种“可替代性(substitutability)”是OOP中最有
效的概念之一。
Booch提出了一个对对象的更加简洁的描述:
第个对象都有状态,行为和标识. 这意味着每一个对象都可以拥有内部数据(它们给出了该对象的状态)和方法(它们产生行为),并且每一个对象都可以唯一地与其他对象相区分开,具体说来,就是每一个对象在内存中都有一个唯一的地址.
每个对象都有一个接口
Aristotle可能是第一个开始详尽研究类型的概念的人;他提过”鸟类,鱼类” 所有的对象都是唯一的,但同时也是具有相同的特性和行为的对象所归属的类的一部分,这种思想被直接应用于第一个面向对象语言Simula-67,它在程序中使用基本关键词class来引入新的类型。 Simula,就象他的名字, 是为了开发诸如经典的“银行出纳员问题(Bank teller problem)”这样的仿真程序而创建的。在银行出纳员问题中,有出纳员、客户、账户、交易和货币单位等许多“对象”。在程序执行期间具有不同的状态而其他方面都相似的对象会被分组到对象的类中,这就是关键词class的由来。创建抽象数据类型(类)是面向对象程序设计的基本概念之一。抽象数据类型的运行方式与内置(built-in)类型几乎完全一致:你可以创建某一类型的变量(按照面向对象的说法,程其为对象或实例),然后操作这些变量(称其为发送消息或请求;你发送消息,对象就能够知道需要做什么)。每个类的成员(member)或元素(element)都共享相同的性质:每个账户都有结余金额,每个出纳都可以处理存款请求等。同时,每个成员都有其自身的状态:每个账户都有不同的结余金额,每个出纳都有自己的名称。因此,出纳、客户、账户、交易等都可以在计算机程序中被表示成为唯一的实体(entity)。这些实体就是对象,每一个对象都属于定义了特性和行为的某个特定的类。
所以,尽管我们在面向对象程序设计中实际所作的是创建新的数据类型,但事实上所有的面向对象程序设计语言都使用Class关键词来表示数据类型。当你看到类型(Type)一
词时,请将其作为类(Class)来考虑,反过来也一样.
既然类被描述成一些有相同元素和行为的对象的集合,类确实是一种数据类型,因为比如实型数字,也有行为和特性的集合.不同的是程序员以问题来定义类而不是被迫用一个存在的表示机器中存储的的数据类型. 你可以根据需求,通过添加新的数据类型来扩展编程语言。编程系统欣然接受新的类,并且给予它们与内置类型相同的管护和类型检查(Type-checking)。
面向对象的方法不仅用于仿真.不管你是否认为任何程序都是对你所设计的系统的仿真,OPP技术的应用可以简单的把一个大问题简化成小问题.
一旦一个类建立,你可以随意定义对象, 然后去操作它们,就像它们是存在于你的待解问题中的元素一样。事实上,面向对象程序设计的挑战之一,就是在问题空间的元素和解空间的对象之间创建一对一的映射。
但是怎样使对象对你的工作有用? 必须有某种方式产生对对象的请求,使对象完成诸如完成一笔交易、在屏幕上画图、打开开关之类的任务。每个对象都只能满足某些请求,这些请求由对象的接口(Interface)所定义,决定接口的便是类型(Type)。以电灯泡为例来做一个简单的比喻:
Light it=new light();
Lt.on();
接口建立了你能为一个特殊对象的请求.然而,但是必须有一段代码来满足你的请求.这样,与隐藏的数据一起,构成了实现.从程序的立场上来看,并没有那么复杂在类型中,每一个可能的请求都有一个方法与之相关联,当你向对象发送请求时,与之相关联的方法就会被调用。此过程通常被总结为:你向某个对象发送消息(产生请求),这个对象便知道此消息的目的,然后执行对应的程序代码。
这里,类型的名字是灯,这个特殊的灯对象的名字是它,你对灯对象做出的请求是打开它,关上它,让它更亮或更暗,你定义这个对象的“引用(reference)”(lt)建立了一个灯对象, 然后调用new方法来创建该类型的新对象。为了向对象发送消息,你需要声明对象的名称,并以圆点符号连接一个消息请求。从预定义类的用户观点来看,这些差不多就是用对象来进行设计的全部。
之前的图是UML(Unified Modelling Language)形式的图,每个类都用一个方框表示,类名在方框的顶部,你所关心的任何数据成员(data member)都描述在方框的中间部分,方法(隶属于此对象的,用来接收你发给此对象的消息的函数)在方框的底部。通常,只有类名和公共方法(Public Method)被示于UML设计图中,因此,方框的中部并不绘出。如果你只对类型感兴趣,那么方框的底部甚至也不需要被绘出。
每个对象都提供服务
当你试图发展或理解一个程序设计,一个最好的方法是考虑对象是服务提供者.你的程序本身将会给使用者提供服务,它可以通过其它类来实现这些服务, 你的目标就是去创建(或者最好是在现有代码库中寻找)能够提供理想的服务来解决问题的对象集合。
一个开始实现的方法是问:” 如果我可以将问题从表象中抽取出来,那么什么样的对象可以马上解决我的问题呢?”例如:假设你在做一个存书的程序.你可以想象一些对象,包括统应该具有某些包括了预定义的簿记输入屏幕的对象,一个执行簿记计算的对象集合,以及一个处理在不同的打印机上打印支票和开发票的对象。也许上述对象中的某些已经存在了,但是对于那些并不存在的对象,它们看起来什么样?它们能够提供哪些服务?它们需要哪些对象才能履行它们的义务?如果你持续这样做,你最终会发现你将到达这样一个节点:你会说“那个对象看起来很简单,以至可以坐下来写代码了”,或者会说“我肯定那个对象已经存在了”。这是将问题分解为对象集合的一种合理方式。
把对象看作是一个服务提供者还有一个好处:它可提高对象的聚合性.高聚合性是软件设计的基本质量之一:意思是软件组成的多个方面(这样一个对象: 尽管它也有可能被用来指代一个方法或一个对象库)组合很好. 人们在设计对象时所面临的一个问题是将过多的功能都填塞在一个对象中。例如,在你的检查打印模式模块中,你可以设计一个对象,它了解所有的格式和打印技术。你可能会发现这些功能对于一个对象来说太多了,你需要的是三个甚至更多个对象,其中,一个对象可以是所有可能的支票排版的目录,它可以被用来查询有关如何打印一张支票的信息;另一个对象或是对象集合可以是一个通用的打印接口,它知道有关所有不同类型的打印机的信息(但是不包含任何有关簿记的内容,它更应该是一个需要购买而不是自己编写的对象);第三个对象通过调用另外两个对象的服务来完成打印任务。因此,每个对象都有一个它所能提供服务的高内聚的集合。在良好的面向对象设计中,每个对象都可以很好地完成一项任务,但是它并不试图多更多的事。就像在这里看到的,不仅允许某些对象可以通过购买获得(打印机接口对象),而且还使对象在某处重用成为可能(支票排版目录对象)。
把对象看做服务提供者是一个伟大的简化工具,它不但在设计过程中很有用,而且当其它人想理解你的代码或重用一个类, 如果他们看出了这个对象所能提供的服务的价值所在的话,它使调整调整对象更加简单.
隐藏的完成
将开发人员分成类创造者(那此创建新数据类型的人)和客户端程序员(那些在其应用中使用数据类型的类消费者)是很有用的.客户端程序员的目标是收集各种用来实现快速应用开发的类. 类创建者的目标是构建类,该类只向客户端程序员暴露必需的部分,而隐藏其它所有部分。为什么要这样呢?因为如果加以隐藏,那么客户端程序员将不能够访问它,这意味着类创建者可以任意修改被隐藏的部分,而不用担心对其他任何人造成影响。隐藏的部份通常代表对象内部敏感的部份,这部份可能被粗心或不知情和客户端程序员破坏,所以将实现隐藏起来减少程序漏洞.
实现隐藏的概念不能被过分强调.在任何中具有许多关系涉及方面的边界是很重要的.当你创建一个类库时, 你就建立了与客户端程序员之间的关系,他们同样也是程序员,但是他们是使用你的类库来构建应用,或者是构建更大的类库的程序员。如果类成员对所有人都是开放的,那么客户端程序员用那些类可以做任何事而且无法约束. 即使你希望客户端程序员不能直接操作你的类中的某些成员,但是如果没有任何访问控制,将无法阻止它。所有的东西都裸露在世界中了.