面向对象软件构造(第2版)-第7章 静态结构: 类 (上)

Examining the software engineering background of our discussion, you have seen the reasons for demanding a better approach to modular design: reusability and extendibility.

研究我们讨论中的软件工程背景,您已经知道到了需要一个更好的方法来模块化设计的原因:复用性和扩充性。

 

You have realized the limitations of traditional approaches: centralized architectures limiting flexibility. You have discovered the theory behind the object-oriented approach: abstract data types. You have heard enough about the problems. On to the solution!

您已经意识到了传统方法的局限性:集中化的架构限制了灵活性。您已经发现了支持面向对象方法的理论:抽象数据类型。你已经听够了相关的疑难杂症。解决方案即将到来!

 

This chapter and the others in part C introduce the fundamental techniques of object-oriented analysis, design and programming. As we go along, we will develop the necessary notation.

C部分中的本章和其它章节介绍了面向对象分析,设计和编程的基本技术。随着研究地深入,我们将逐步展现所需要的符号。

 

Our first task is to examine the basic building blocks: classes.

我们的第一项任务就是要研究基本的组成部分:类。

 

7.1 OBJECTS ARE NOT THE SUBJECT

7.1 对象不是主题

 

What is the central concept of object technology?

对象技术的核心概念是什么?

 

Think twice before you answer “object”. Objects are useful, but they are not new. Ever since Cobol has had structures; ever since Pascal has had records; ever since the first C programmer wrote the first C structure definition, humanity has had objects.

在您回答对象之前,请三思。对象是有其作用,但它们并不是新的概念。Cobol有结构Pascal存在纪录自从第一位C程序员写出了第一个C结构定义之后,我们就有了对象。

 

Objects remain important to describe the execution of an O-O system. But the basic notion, from which everything in object technology derives, is class, previewed in the preceding chapter. Here again is the definition:

对象依然保持着描述OO统执行的重要性。但是基本的概念却类(class,在对象技术中所有的一切都起源于它。这在上一章已经介绍过了,这里重复一下它的定义:

 

Definition: class

A class is an abstract data type equipped with a possibly partial implementation.

定义:类

类是一个具有可能部份实现的抽象数据类型。

 

 

Abstract data types are a mathematical notion, suitable for the specification stage (also called analysis). Because it introduces implementations, partial or total, the notion of class establishes the necessary link with software construction — design and implementation. Remember that a class is said to be effective if the implementation is total, deferred otherwise.

抽象数据类型是一个数学上的概念,适用于规格阶段也叫分析阶段 因为它引进了部份或完全实现,所以类的概念建立了软件构造——设计和实现之间的必然联系。记住,如果实现是完全的,类被认为是有效的,否则为延期的。

 

Like an ADT, a class is a type: it describes a set of possible data structures, called the instances of the class. Abstract data types too have instances; the difference is that an instance of an ADT is a purely mathematical element (a member of some mathematical set), whereas an instance of a class is a data structure that may be represented in the memory of a computer and manipulated by a software system.

就象ADT,类是一个类型:它描述了一套可能的数据结构集合,称为类的实例instances)。抽象数据类型也有实例;不同之处是一个ADT的实例是一个纯粹的数学元素某些数学集合的成员,而一个类的实例是一个数据结构,其被描述在计算机的内存中,并被软件系统操作。

 

For example if we have defined a class STACK by taking the ADT specification of the previous chapter and adding adequate representation information, the instances of that class will be data structures representing individual stacks. Another example, developed in the rest of this chapter, is a class POINT modeling the notion of point in a two dimensional space, under some appropriate representation; an instance of that class is a data structure representing a point. Under one of the representations studied below, the cartesian representation, each instance of POINT is a record with two fields representing the horizontal and vertical coordinates, x and y, of a point.

例如,如果采用上一章节中的ADT规格并加入充分的表示法信息,我们定义了一个类STACK那么类的实例将是代表着独立栈的数据结构。在本章下面所用的另一个例子是一个类POINT,在适当的表示法之下模拟了二维空间中点的概念;那个类的实例是一个代表点的数据结构。在下面要学习的两个表示法之一的笛卡尔表示法之中,每个POINT的实例是一个有着两个字段的纪录,这两个字段表示了一个点的水平和垂直坐标xy

 

The definition of “class” yields as a byproduct a definition of “object”. An object is simply an instance of some class. For example an instance of class STACK — a data structure representing a particular stack — is an object; so is an instance of class POINT, representing a particular point in two-dimensional space.

义产生了一个副产物:对象义。一个对象只是某个类的一个实例例如一个STACK——表示一个特殊栈的数据结构——的实例是一个对象;而一个POINT的实例代表了维空间中的一个特殊点。

 

The software texts that serve to produce systems are classes. Objects are a run-time notion only: they are created and manipulated by the software during its execution.

用于生成系统的软件代码是类。对象只是一个运行时的概念:它们在软件的执行期间被创造和操纵。

 

The present chapter is devoted to the basic mechanisms for writing software elements and combining them into systems; as a consequence, its focus is on classes. In the next chapter, we will explore the run-time structures generated by an object-oriented system; this will require us to study some implementation issues and to take a closer look at the nature of objects.

本章致力于编写软件元素并使之成为系统的基本机制;作为结果,它的焦点在类上。在下一章中,我们将探索面向对象系统所生成的运行时结构;这将要求我们学习一些实现的议题,并进一步了解对象的本质。

 

7.2 AVOIDING THE STANDARD CONFUSION

7.2 避免一般性的混乱

 

A class is a model, and an object is an instance of such a model. This property is so obvious that it would normally deserve no comments beyond the preceding definitions; but is has been the victim of so much confusion in the more careless segment of the literature that we must take some time to clarify the obvious. (If you feel that you are immune to such a danger, and have avoided exposure to sloppy object-oriented teaching, you may wish to skip this section altogether as it essentially belabors the obvious.)

一个类是一个模型,一个对象就是这个模型的一个实例。这个属性如此的明显,以至于它通常不需要在先前的定义之外再解释一番;但是它曾经是在许多草率的文献中引发诸多混乱的受害者,我们必须要花一些时间来澄清这个显而易见的事情。如果您认为您不会受到这种危险的感染,并且不想暴露在这种面向对象的喋喋不休的教诲之下,由于它基本上就是在嘲讽,那么您也许希望完全地跳过这个部

 

What would you think of this?

您意下如何?

 

Among the countries in Europe we may identify the Italian. The Italian has a mountain chain running through him North-South and he likes good cooking, often using olive oil. His climate is of the Mediterranean type, and he speaks a beautifully musical language.

在欧洲的国家中,我们可以识别意大利人。意大利有一个贯穿南北的山脉,他喜欢精美的食物,常常使用橄榄油。他的气候是地中海类型,并操着一种优美的具有旋律的语言。

 

If someone in a sober state talked or wrote to you in this fashion, you might suspect a new neurological disease, the inability to distinguish between categories (such as the Italian nation) and individuals members of these categories (such as individual Italians), reason enough to give to the ambulance driver the address of Dr. Sacks’s New York clinic.

如果有人在清醒的状态下用这种方式和您交谈话或写信给您,您也许怀疑一个新的神经病人,他丧失了在范畴如意大利国家这些范畴中的独立个体独立的意大利人之间的区别能力,有足够的原因把他交给救护车司机送往Dr. Sacks纽约诊所。

 

Yet in the object-oriented software literature similar confusions are common. Consider the following extract from a popular book on O-O analysis, which uses the example of an interactive system to discuss how to identify abstractions:

在面向对象的软件文献中有着相似的混乱。看看从一本流行的OO分析的书中摘取的一段,它使用了一个交互式系统的例子来谈论如何辨别抽象:

 

[W]e might identify a “User” Object in a problem space where the system does not need to keep any information about the user. In this case, the system does not need the usual identification number, name, access privilege, and the like. However, the system does need to monitor the user, responding to requests and providing timely information. And so, because of required Services on behalf of the real world thing (in this case, User), we need to add a corresponding Object to the model of the problem space.

我们可以在一个问题空间中识别一个“用户”对象,这个空间中的系统并不需要保持用户的任何信息。在这种情况下,系统并不需要通常使用的识别码,姓名,使用权限等等。然而,系统需要监控用户,响应请求并提供及时的信息。因此,因为所请求的服务代表了真实世界的东西(这里是用户),所以我们需要加上一个相应的对象来模拟问题空间。

 

In the same breath this text uses the word objects, user and thing in two meanings belonging to entirely different levels of abstraction:

这段文本同时用对象事情来表达二个含意,而这二个含意属于完全不同的抽象层次:

 

• A typical user of the interactive system under discussion.

·一个讨论中的交互系统的典型用户。

 

• The concept of user in general.

·通常意义上的用户概念

 

Although this is probably a slip of terminology (a peccadillo which few people can claim never to have committed) rather than a true confusion on the authors’ part, it is unfortunately representative of how some of the literature deals with the model-instance distinction. If you start the study of a new method with this kind of elementary mix-up, real or apparent, you are not likely to obtain a rational approach to software construction.

虽然这有可能只是一个术语(一个小小的过失,很少有人能声称不会犯这样的错误)上的笔误而不是作者造成的真正混乱,但是这不幸地代表了某些文献如何处理模型-实例的差别。如果您用这种真正的或貌似的概念混合在一起来开始一个新方法的研究,那么您不可能得到一种软件构造的合理方法。

 

The mold and the instance

模型和实例

 

Take this book — the copy which you are currently reading. Consider it as an object in the common sense of the term. It has its own individual features: the copy may be brand new, or already thumbed by previous readers; perhaps you wrote your name on the first page; or it belongs to a library and has a local identification code impressed on its spine.

拿起本书——您当前正在阅读的拷贝。把它视为常规术语中的一个对象。它有它自己独立的特性:拷贝也许是全新的,或者上一个读者已经翻阅过了;或许您在扉页上签了您的名字;或是它属于图书馆并且在书脊上印着标识码。

 

The basic properties of the book, however, such as its title, publisher, author and contents, are determined by a general description which applies to every individual copy: the book is entitled Object-Oriented Software Construction, it is published by Prentice Hall, it talks about the object-oriented method, and so on. This set of properties defines not an object but a class of objects (also called, in this case, the type of these objects; for the time being the notions of type and class may be considered synonymous).

然而,书的基本属性,例如它的标题,出版商,作者和内容,取决于应用到每个单独拷贝上的通用描述:书名为面向对象软件构造,它由Prentice Hall出版,它谈论面向对象的方法,等等。这些属性集合定义了不是一个对象,而是对象的一个类(在这种情况中也叫这些对象的类型type);暂时把类型和类两个概念认为是同义词)。

 

Call the class OOSC. It defines a certain mold. Objects built from this mold, such as your copy of the book, are called instances of the class. Another example of mold would be the plaster cast that a sculptor makes to obtain an inverted version of the design for a set of identical statues; any statue derived from the cast is an instance of the mold.

把它称之为类OOSC。它定义了一个特定的模型。从这个模型中建立的对象,例如您的书的拷贝,叫做类的实例instances)。模型的另一个例子是石膏模型,雕刻家为设计一套相同的雕像制作出一个倒置的版本;所有从石膏模型中获得的雕像都是模型的实例。

 

In the quotation from The Name of the Rose which opens part C, the Master is explaining how he was able to determine, from traces of the snow, that Brownie, the Abbot’s horse, earlier walked here. Brownie is an instance of the class of all horses. The sign on the snow, although imprinted by one particular instance, includes only enough information to determine the class (horse), not its identity (Brownie). Since the class, like the sign, identifies all horses rather than a particular horse, the extract calls it a sign too.

C部分的引文The Name of the Rose,导师解释了他如何能从雪的痕迹中确定Abbot的马Brownie先前从这里走过。Brownie是所有马的类的一个实例。雪上的标记,虽然由一个特殊的实例留下的,但是其包括的信息只能够用来确定类(马),而不是它的特征(Brownie)。由于类就象标志一样识别所有的马而不是一匹特殊的马,所以节选引文也称它为标志。

 

Exactly the same concepts apply to software objects. What you will write in your software systems is the description of classes, such as a class LINKED_STACK describing properties of stacks in a certain representation. Any particular execution of your system may use the classes to create objects (data structures); each such object is derived from a class, and is called an instance of that class. For example the execution may create a linked stack object, derived from the description given in class LINKED_STACK; such an object is an instance of class LINKED_STACK.

同样的概念正好适用于软件对象。您将在您的软件系统中编写的就是类的描述,就象类LINKED_STACK描述了在某个表示法中栈的属性一样。您的系统中任何特定的执行也许使用了类去创建对象(数据结构);每个这样的对象都从类中派生出来,称之为类的实例(instance)。例如(软件)执行可能创建了一个链接栈的对象,派生于类LINKED_STACK中给定的描述;这样的对象就是类LINKED_STACK的一个实例。

 

The class is a software text. It is static; in other words, it exists independently of any execution. In contrast, an object derived from that class is a dynamically created data structure, existing only in the memory of a computer during the execution of a system.

类是软件代码。它是静态的;换句话说,它的存在独立于所有的执行。相反,从类中派生出的对象是一种动态创造的数据结构,仅在系统的执行期间存在于计算机的内存中。

 

This, of course, is in line with the earlier discussion of abstract data types: when specifying STACK as an ADT, we did not describe any particular stack, but the general notion of stack, a mold from which one can derive individual instances ad libitum.

当然,这符合之前的抽象数据类型讨论:当指定STACKADT的时候,我们并没有描述任何特殊的栈,而是栈的一般概念,一个从中可以任意获得单独实例的模型。

 

The statements “x is an instance of T” and “x is an object of type T” will be considered synonymous for this discussion.

在这次讨论中,xT的实例”和x是类型T的对象”的声明将被认为是同义的。

 

With the introduction of inheritance we will need to distinguish between the direct instances of a class (built from the exact pattern defined by the class) and its instances in the more general sense (direct instances of the class or any of its specializations).

随着继承的介绍,我们需要区别类的直接实例direct instances(从由类定义的精确模式中构建)和常规意义上的实例(类的直接实例或任何类的特化)。

 

Metaclasses

元类

 

Why would so many books and articles confuse two so clearly different notions as class and object? One reason — although not an excuse — is the appeal of the word “object”, a simple term from everyday language. But it is misleading. As we already saw in the discussion of seamlessness, although some of the objects (class instances) which O-O systems manipulate are the computer representations of objects in the usual sense of the term, such as documents, bank accounts or airplanes, many others have no existence outside of the software; they include in particular the objects introduced for design and implementation purposes — instances of classes such as STATE or LINKED_LIST.

为什么许多书和文章混淆类和对象这二个截然不同的概念?原因之一——虽然不是借口——是单词对象的感染力,一个日常所用的简单术语。但这是误导。就象我们在无缝的讨论中已经知道的,虽然OO系统操作的某些对象(类的实例)是对象在术语的通常意义里的计算机描述,如文件,银行帐户或者飞机,但是许多其它的对象没有脱离软件而存在;特别是它们包括了为设计和实现的目的而引进的对象——类的实例,如STATELINKED_LIST

 

Another possible source of confusion between objects and classes is that in some cases we may need to treat classes themselves as objects. This need arises only in special contexts, and is mainly relevant to developers of object-oriented development environments. For example a compiler or interpreter for an O-O language will manipulate data structures representing classes written in that language. The same would hold of other tools such as a browser (a tool used to locate classes and find out about their properties) or a configuration management system. If you produce such tools, you will create objects that represent classes.

对象和类之间混乱的另一个可能来源是在某些情况下我们也许需要把类本身看作对象。这个需要只会出现在特别的环境里,并且主要与面向对象开发环境的开发者有关。例如一个OO语言的编译器或解释器操作着数据结构,这些数据结构代表着编写在语言中的类。样地情况出现在其它的工具中例如浏览器(一个用来找出类并得到它们属性的工具或配置管理系统。如果您编写这样的工具,您将会创建代表类的对象。

 

Pursuing an analogy used earlier, we may compare this situation to that of a Prentice Hall employee who is in charge of preparing the catalog of software engineering titles. For the catalog writer, OOSC, the concept behind this book, is an object — an instance of a class “catalog entry”. In contrast, for the reader of the book, that concept is a class, of which the reader’s particular copy is an instance.

继续使用先前用过的类比们可以拿这个情况与负责准备软件工程书目目录的Prentice Hall雇员相比较。对于目录作者,本书OOSC之后的概念是一个对象——目录条目的实例。相反,对于本书的读者而言,那个概念是类,读者的个人拷贝才是实例。

 

Some object-oriented languages, notably Smalltalk, have introduced a notion of metaclass to handle this kind of situation. A metaclass is a class whose instances are themselves classes — what the Name of the Rose extract called “signs of signs”.

一些面向对象的语言,特别象Smalltalk,引进了元类(metaclass)的概念来处理这类情况。一个元类是一个类,类的实例是类的本身——就是Name of the Rose节选中所说的“标志的标志”。

 

We will avoid metaclasses in this presentation, however, since they bring more problems than benefits. In particular, the addition of metaclasses makes it difficult to have static type checking, a required condition of the production of reliable software. The main applications of metaclasses are better obtained through other mechanisms anyway:

然而在这次介绍中,我们将避免元类,由于它们弊大于利。尤其元类的加入使得静态类型的检查更加困难,而这个检查是软件产品可靠性的必要条件。总之,元类的主要用途可以更好地通过其它的机制中而获得:

 

• You can use metaclasses to make a set of features available to many or all classes. We will achieve the same result by arranging the inheritance structure so that all classes are descendants of a general-purpose, customizable class ANY, containing the declarations of universal features.

·您可能使用元类来建立一组对大量的或是所有的类都有效的特性。定义一个多用途的,可自定义的类ANY,其包含通用特性的声明,所有的类都是它的后代,通过使用这样的继承结构我们可以达到同样的效果。

 

• A few operations may be viewed as characterizing a class rather than its instances, justifying their inclusion as features of a metaclass. But these operations are few and known; the most obvious one is object creation — sufficiently important to deserve a special language construct, the creation instruction. (Other such operations, such as object duplication, will be covered by features of class ANY.)

·一些运算也许被看成是类的特征,而不是类的实例,它们的内容也证实为一个元类的特性。但是,这些运算并不多且为人熟知;最明显的要算是对象创建——其重要性足以把它认为是一个特殊语言构造,创建指令。(其它的类似运算,如对象复制,将被类ANY的特性所包含。)

 

• There remains the use of metaclasses to obtain information about a class, such as a browser may need: name of the class, list of features, list of parents, list of suppliers etc. But we do not need metaclasses for that. It will suffice to devise a library class, E_CLASS, so that each instance of E_CLASS represents a class and its properties. When we create such an instance, we pass to the creation instruction an argument representing a certain class C; then by applying the various features of E_CLASS to that instance, we can learn all about C.

·这里还剩下使用元类来获得一个类的信息,如类浏览器所需要的:类的名字,特性列表,父类列表,供应者列表等等。但是对于这些,我们并不需要元类。设计一个库类E_CLASS就可以满足了,E_CLASS的每一个实例代表了一个类和其属性。当我们创建这样的一个实例的时候,我们给创建指令传递一个特定类C为参数;接着,通过把E_CLASS的各种特性应用到那个实例上,我们能够知道C的所有一切。

 

In practice, then, we can do without a separate concept of metaclass. But even in a method, language or environment that would support this notion, the presence of metaclasses is no excuse for confusing molds and their instances — classes and objects.

那么,实际上不用一个单独的元类概念我们也能做到这一切。但是,即使在一个支持这个概念的方法,语言和环境中,对于造成模型和其实例——类和对象——之间的混乱,元类的出现也不一定是正确的

 

7.3 THE ROLE OF CLASSES

7.3 类的角色

 

Having taken the time to remove an absurd but common and damaging confusion, we may now come back to the central properties of classes, and in particular study why they are so important to object technology.

花费了一些时间来消除一个荒谬但却普通并具破坏性的混乱,现在我们可以回到类的重要属性上来,同时要特别地研究为什么对对象技术而言它们很重要。

 

To understand the object-oriented approach, it is essential to realize that classes play two roles which pre-O-O approaches had always treated as separate: module and type.

要理解面向对象方法,意识到类扮演了两个角色是必要的,OO之前的方法总对把两个角色分开对待:块和类型。

 

Modules and types

块和类型

 

Programming languages and other notations used in software development (design languages, specification languages, graphical notations for analysis) always include both some module facility and some type system.

编程语言和用于软件开发的其它符号设计语言,规格语言,图形分析符号总是同时包括了某些模块工具和某些类型系统。

 

A module is a unit of software decomposition. Various forms of module, such as routines and packages, were studied in an earlier chapter. Regardless of the exact choice of module structure, we may call the notion of module a syntactic concept, since the decomposition into modules only affects the form of software texts, not what the software can do; it is indeed possible in principle to write any Ada program as a single package, or any Pascal program as a single main program. Such an approach is not recommended, of course, and any competent software developer will use the module facilities of the language at hand to decompose his software into manageable pieces. But if we take an existing program, for example in Pascal, we can always merge all the modules into a single one, and still get a working system with equivalent semantics. (The presence of recursive routines makes the conversion process less trivial, but does not fundamentally affect this discussion.) So the practice of decomposing into modules is dictated by sound engineering and project management principles rather than intrinsic necessity.

一个模块是一个软件分解单元。我们已经在前面的章节中学习过了模块的种形式,如例程和包。不考虑模块结构的确切选择,我们可以把模块的概念叫作一个语法(syntactic)概念,因为分解到模块只影响软件代码的形式,并不影响软件的功能;则上把任何的Ada程序写成一个包,或者把任何的Pascal程序写成一个主程序的确是有可能的。当然没有人推荐这样的方法,并且任何出色的软件开发者都将使用正在采用的语言的模块工具把他的软件分解成易于管理的片断。但是如果我们采取一个象Pascal这样的现有程序,那么我们总是可以把所有的模块合并成一个单独的模块,仍然能得到一个具有相同语义的运行系统。递归例程的出现使转换过程更加简单,但是基本上不影响本次讨论。因此分解成模块的习惯一般由健全的工程和项目管理原则控制而并非本质上的需要。

 

Types, at first sight, are a quite different concept. A type is the static description of certain dynamic objects: the various data elements that will be processed during the execution of a software system. The set of types usually includes predefined types such as INTEGER and CHARACTER as well as developer-defined types: record types (also known as structure types), pointer types, set types (as in Pascal), array types and others. The notion of type is a semantic concept, since every type directly influences the execution of a software system by defining the form of the objects that the system will create and manipulate at run time.

首先,类型是完全不同的概念。 类型是某些动态对象的静态描述:在软件系统的执行中被处理的各种各样的数据元素。类型集合通常包括预定义类型,例如INTEGER CHARACTER 开发者定义的类型:记录类型(或是结构类型),指针类型,集合类型(如在Pascal中所用),数组类型和其它。类型的概念是一个语义(semantic概念,这是由于通过定义在运行期间系统将创建并且操作的对象形式,每个类型直接地影响软件系统的执行。

 

The class as module and type

具备块和类型的类

 

In non-O-O approaches, the module and type concepts remain distinct. The most remarkable property of the notion of class is that it subsumes these two concepts, merging them into a single linguistic construct. A class is a module, or unit of software decomposition; but it is also a type (or, in cases involving genericity, a type pattern).

OO方法中,模块和类型概念泾渭分明。类概念中最伟大的属性就是它囊括了这二个概念,把它们合并进了一个单一的语言架构。一个类就是一个软件分解模块或者单元但它也是一个类型或是在泛型中的一个类型模式

 

Much of the power of the object-oriented method derives from this identification. Inheritance, in particular, can only be understood fully if we look at it as providing both module extension and type specialization.

面向对象方法的许多能力都同此有关。尤其是,只有在我们把继承看作是同时提供模块延伸和类型特殊化的情况下,它才能被充分地了解。

 

What is not clear yet is how it is possible in practice to unify two concepts which appear at first so distant. The discussion and examples in the rest of this chapter will answer this question.

仍然不能确定的问题是如何在实践中把这两个起初看上去截然不同的概念统一起来。本章下面的讨论和例子将回答这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值