[译]OOSE第5章:面向对象的程序设计 5.3 Classes and instances

5.3 Classes and instances

In object-oriented languages, each object is described by a class. This class is both a module for source code and a type for the class instances. The programming language Ada comes close to this approach with the package concept, but the package in Ada is not a type. Inside a package, however, types can be defined with associated operations. These types can in turn be used to create objects, where the package's interface may specify the operations that can be performed on the object.

在面向对象的编程语言中,每一个对象都是通过类来进行描述的.这个类即是一个源代码的模块,又是一个类相关实例集合的一个模版a type.. ADA这种编程语言利用包的概念和这种设计方案更加接近,但是在ADA中应用的包的概念并不是一个模版a type. 在一个包的内部,不同的模版type.可以通过对应的操作来进行定义这些不同的模版type又可以进一步 被用来创造对象,而相关包的接口可以用来定义能够施加到对象上的操作集合.

A class defines the operations that can be performed on an instance. It also defines the variables of the instance. A variable associated with a specific instance is often called an instance variable. These instance variables store the instance's state. All object-oriented languages have instance variables, even though they may have a different name. In Eiffel, the variable is called a field and the declaration of it is called an attribute, in accordance with Eiffel's main source of inspiration, Simula. The reason for calling them instance variables, and not just variables, is that some languages, such as Smalltalk and, in some senses, C++, have other variables which are only associated with the class. These are called class variables. Additionally, variables could also be local to a specific operation. These are called temporary variables.

个类定义了和他相关的每一个实例中所能够执行的所有操作.他同时也定义了这个实例所拥有的所有变量和一个对象所关联的一个变量通常被叫做一个实例变量.These instance variables store the instance's state. All object-oriented languages have instance variables, even though they may have a different name. 这些实例变量保存了变量的状态所有的面向对象的编程语言都拥有实例变量,虽然在不同的编程语言中的命名是不同的. Eiffel ,一个变量被叫做一个区域数值(a field),而对这个变量的声明被叫做一个属性an attribute这种命名方式是来自与Eiffel最主要的灵感源泉.我们需要明确定义实例变量,而不仅仅叫做变量的原因是在于,在某些编程语言中,比如Smalltalk,C++,可以定义仅仅和类有关联的变量这些被叫做类变量class variables. 此外,和一个特定操作相关的局部变量也可以单独定义这些变量则被称为临时变量.

Instances are created from the classes which declare the instance variables. The current values of these variables, though, are stored in the instances. The operations are thus defined in the class. An alternative is that, as with instance variables, they should exist in the instances as well. However, this would create much duplication, as the operations are identical for all instances of a specific class. Normally, therefore, each instance has a reference, instanceOf, to the class which contains all the operations (see Figure 5.3). By means of this reference, each instance is linked to its associated class. In such a way, the instances only store information unique to the individual instance, namely the instance variables, while information common to all instances, namely operations and (possibly) class variables, is stored in the class.

多个实例是由类进行创建的,其中类负责声明实例变量. 然而每一个实例变量的当前取值则是由实例来负责保存的. 另外,实例的操作则是由类来集中定义的关于实例的操作还有一种可选的定义方式,也就是类似于实例变量实例的操作也应该在每一个实例中单独存在,但是这种实现方式会产生大量的冗余,因为针对一个特定类所产生的所有的实例来说操作operations都是完全相同的基于这一点所有的实例都应该有一个参考编号a reference,也就是我们通常所说的instanceOf,来关联索引到一个类这个类来集中管理所有的操作.详细的含义请参考图5-3. 利用这个参考编号reference每一个实例都可以连接到一个和他相关联的类通过这种方式每一个实例仅仅需要保留和他相关联特有的信息,也就是我们所说的实例变量而作为那些和所有实例都相同的信息结构部分,通常叫做操作和类变量,则在类中进行保存.

When an instance is to perform an operation, its associated class selects the required operation and performs it using the instance's variables. This means that when an operation reads or writes an instance variable, the current instance's variables are used. The operation is selected by finding an operation that has the same name as the stimulus (and, possibly, even the correct parameter set up) The machinery which interprets a stimulus sent to an instance therefore operates according to Algorithm 5.1.

当一个实例将要执行一个操作,和这个实例所关联的类负责选择需要的操作,并请使用相关的实例变量来执行这个操作这就意味着假如一个操作来读,或者写一个实例变量当前的实例变量被操作所使用其中操作的选择方法是通过搜索和激励名称相同的操作来确定.( 在有些场合下也可以通过正确的参数来建立). 其中当一个激励发送到一个实例以后相关操作的选择方法和机制可以根据算法5.1来解释.

Algorithim 5.1 Operation of the machinery to interpret a stimulus

Given an instance and a stimulus to the instance:

1. In the environment referred to by instanceOf, that is, the associated class, the operation corresponding to the stimulus' name is searched for.

2. Interpret the selected operation using both the stimulus' parameters and the instance's environment.

3. Return any values from the execution of the operation.

Algorithim 5.1 激励和操作关联系的解释机制

确定一个实例和一个与实例相关的激励

1. In the environment referred to by instanceOf, that is, the associated class, the operation corresponding to the stimulus' name is searched for.根据instanceOf这个参数所确定的应用上下文环境定位到相关的类由类根据激励的名称进行搜索是否有匹配的操作.

2. Interpret the selected operation using both the stimulus' parameters and the instance's environment. 同时使用激励携带的参数和具体的实例应用上下文环境来解释被选择匹配的操作.

3. Return any values from the execution of the operation. 返回当前操作执行后所获取的结果.

The algorithm uses the stimulus name to access the required operation from within a table in the class. When a stimulus is sent to an object, an operation is performed by applying the algorithm that uses both the stimulus and a specified environment.

  上面介绍的算法使用激励名称在类的操作列表中进行搜索和匹配操作当一个激励发送到一个对象中一个操作将被执行具体操作执行机制是通过调用一个关联应用激励名称和一个特定应用上下文环境的算法来确定

As the instance's environment only consists of information unique to itself, and all operations are stored in the instance's class, one must be able to perform the same operations on all instances. The difference is in the environments in which they are executed. Normally, all operations can access all instance variables. The operation environment is thus the current instance's environment (see Figure 5.4).

因为一个实例对象的应用上下文环境中仅仅包含和他自己相关的独有的信息,而所有的操作都是在实例对象所归属的类中保留,所以执行激励操作映射的算法必须能够针对所有的实例执行相同的操作.唯一的区别是在于操作在不同对象实例中所执行应用环境上下文是各不相同的.通常所有的操作能够接入所有的实例变量而操作的应用上下文环境就是当前的实例环境详细的分析参考图5-4

For an instance to be able to send a stimulus to another instance, a variable will have to exist to reference the other instance. Figure 5.5 illustrates an example of how a variable, a Person, in the instance Mary, refers to another instance, Tom. Thus, in order to send a stimulus Jump to Tom, the instance Mary would need to execute the following:

aPerson.Jump

对于一个实例对象来说如果想发送一个激励给另外一个实例对象这个实例对象必须要能够拥有一个变量来索引到另外一个对象.:5-5解释了一个这样的案例在实例对象Mary中的一个变量a Person,是如何索引到另外一个实例对象TOM中去的这样,为了向TOM发送一个激励对象实例Mary必须要执行如下的操作.

aPerson.Jump

当变量aPerson索引到的实例对象接收到这个激励,上面介绍的算法将被执行,这样一来TOM将解释Jump这个激励并执行和这个操作相关联的行为.

Encapsulation, and the approach from abstract data types, mean that there is only one way to affect an object's state, and that is through its operations. Thus variables can only be directly accessed by defining an appropriate operation. This approach is chosen in Smalltalk, for instance. It is recommended, though, that if an operation l» to rend a variable, then the operation should have the same name as I he variable. In Simula, which is an old language, all instance variables are accessible even from outside the object, unless the variable has been explicitly declared as protected. In Eiffel, a compromise between the above two methods has been made: all instance variables are inaccessible, unless the opposite is explicitly stated. This means that if we execute the expression:

Age := Aperson.myAge;

in, for example, Eiffel or Simula, we do not really know if the operation myAge is performed or if we only read the variable myAge. This is an elegant solution since we could change the implementation without changing an object's clients.

  封装Encapsulation,以及来源于抽象数据类型的方法意味着影响对象状态的唯一途径,是通过对象的操作接口这样一来对象的变量集合仅仅能够通过定义一种合适操作的方式来直接进行读写操作.  这种方式(approach)Smalltalk 这种编程语言中被采用举个例子来说,加入我们想定义一个操作来读一个变量推荐的方式是操作的名称最好能够和变量的名称是相同的.Simula这种古老的编程序语言中所有的实例变量缺省可以被外部的对象所读取,除非这些对象事先被声明为保护protected.的特性.Eiffel,这种编程语言中,关于实例变量的读取方式采用的是上述两种方法的组合所有的实例变量缺省定义为不可读取,除非事先已经明确的定义了相反的属性,着就意味着假如我们想执行如下的表达方式 

Age := Aperson.myAge;

举个例子,Eiffel or Simula,这种编程序语言中我们不知道是否myAge这个操作是被执行,或者我们是仅仅读取了变量myAge. 这是一种非常智慧的解决方案因为我们可以在不影响一个对象相关客户的情况下来自由的改变操作的实现方式.

Some languages also support the notion of class variables and class operations. An example of the information class variables may contain is how many instances are created from this class. Several programming languages do not allow the programmer to declare and use class variables. This is the case in Eiffel, for example, where the distinction between the class and the instance is carefully made. The class is viewed as a description, or the program text, while instances are viewed as executions of the program text. Thus instances are the only things that execute during run-time, and not classes. In Smalltalk, and to a certain extent in Objective-C, classes are regarded as instances of a metaclass (see the box on classes as objects). In C++, the programmer hasn't really the capability to declare class variables, but can declare an instance variable as 'static', which gives all instances the same value for this variable. In such a way, it can be used as a class variable.

有一些编程语言也支持对类变量的标识和类操作的定义.举个例子来说,在类变量class variables的信息中,程序设计者能够规定一个特定的类可以激活多少个实例.有一些编程语言则不允许程序设计者来声明和使用类变量.Eiffel中就是采用的这样种策略举个例子来说Eiffel中的程序设计中关于类和实例的应用是严格的区分开的类被看成一个描述,或者是程序文本,然而实例则是被看成程序文本的具体装载执行和应用. 这样实例是唯一存在于运行环境中的实体并发挥应有的计算功能,而类则不会在运行环境中存在Smalltalk,以及在Objective-C的扩展中,类被认为是元类的实例(参考后续的阅读材料类作为对象) .C++,程序设计者是没有能力来声明类变量的,但是可以声明一种叫做'static'型的实例变量这种类型的变量在所有的实例中是完全相同的取值基于这样一种方式,也可以是被看作类变量.

Class as object

类作为对象

Some object-oriented programming languages also view classes as objects, that is, as instances of another class. This is the case in Smalltalk and Objective-C. An advantage of this is that it is possible to send a stimulus to a class and thus affect all its (existing and not yet created) instances. If, for example, we want all cars manufactured from now on to be blue, it is easy to express this using class variables and operations. By regarding classes as objects, a more flexible system is obtained, allowing classes to be modified during execution (which makes it more difficult to understand the classes).

  有一些面向对象的编程语言也把类看成是对象也就是说是另外一个类的实例集合这就是这种设计方式的一个好处在于有可能对一个类发送一个激励,这样一来就可以影响他下面所有的实例(已经存在和那些还没有被创建的).假如,举个例子来说,如果我们希望所有的汽车从现在开始出厂时就是蓝色我们可以非常容易的利用类变量和类操作来实现这个目标而假如我们把类看成是对象我们就拥有一个更加灵活的系统运行机制类在运行的环境中被修改(但是同时,会导致类的理解更加困难)

As classes are now referred to as instances, they must be instances of some class. This class is often called a metaclass. Each class has therefore been supplied with a reference, instanceOf, which refers to this metaclass. Figure 5.6 illustrates the use of a metaclass. A metaclass contains operations which all classes can understand. 

因为不同的类现在被看成是实例他们也必须是其他一些类的实例这种高层次的类通常被叫做一个元类metaclass. 这样一来每一个类都必须一个参考索引(reference)来支持, instanceOf,来指向这个元类5.6 解释了关于元类的应用一个元类metaclass.包含特定的操作这些操作所有的类都能够理解.

Thus all classes have, at least, the protocol defined by the metaclass. For example, the operation 'new' is often defined in the metaclass. In Smalltalk-78, there is only one metaclass common for all classes, but in SmaIltalk-80, each class has an individual metaclass. In this way, a whole shadow hierarchy is found behind the 'real' class hierarchy.

样一来,所有的类,至少拥有了元类所定义的协议操作举个例子来说在元类中通常会定义创建'new'的操作Smalltalk-78,所有的类是共用一个元类,而在SmaIltalk-80,每一个类都拥有自己独立的元类这样一来,我们可以定义一个完整层次化的影子结构(a whole shadow hierarchy)被定义好用于映射客观世界中的层次化类结构.

Which class is the metaclass an instance of? In Smalltalk-78, the problem of this potential limitless chain has been solved by naming the root class Object as the metaclass' instanceOf. In Smalltalk-80, the solution is more complicated.

 那么元类又是那一个更高层次类的实例呢In Smalltalk-78,这种没有尽头的递归链条结构的解决方式是通过定义一个根类那么元类就是根类的实例而在Smalltalk-80,解决方案则更加复杂.

 Metaclasses are really only a method for implementing the class concept and the underlying system. Even if it is possible, the average programmer should not use metaclasses. The more advanced user can  ,by means of modifying the metaclasses, modify the language's syntax and semantics; but, as mentioned, this is not recommended for the average programmer.

 元类这种概念仅仅是一种用于实施类概念和相关地层系统的方法虽然这是一种可用的方法,但是一般水平的程序设计人员则最好不要使用元类一些熟练掌握面向对象编程的高级程序设计人员可以利用对元类的调整,来变更程序的语法和语意,但是正如前面所提到的,对一般水平的程序设计人员则不建议这样做.

Languages such as Eiffel, C++ and Simula have chosen not to consider classes as objects. In Eiffel, this is a very deliberate choice, as the class is regarded as implementing a type, while the object is regarded as an instance of this type. The class is static and described in the program text, while the instance is dynamic and exists only during execution. Thus, in Eiffel, the distinction between description and corresponding execution is made fundamental. The aim with this approach is to avoid any misunderstanding and obtain a clear distinction between class and instance.

Eiffel, C++ and Simula这样一些编程语言则选择不把类当作对象来处理Eiffel,这是一个非常理所当然的选择,因为类是被认为是一个类型的实现而对象则被看作是这个类型的一个实例具体来说类被看做是固定静止(static),并在程序文本中进行描述,而实例则是动态的,他仅仅存在于执行过程中的运行环境中这样一来在Eiffel,关于程序描述和程序对应的执行在非常基础的层面被明确的区分开.这种设计方式的目标在于避免混淆的理解,并且能够对类和实例进行明确的区分.

Normally, operations are only performed on instances, but some languages allow operations to be performed directly on the class. In the same way as with instance and class variables, we can also have instance operations and class operations. Class operations are normally used to operate on class variables or to create new instances. In Smalltalk, class operations are common, while in Eiffel, they have been avoided so as to separate clearly the description from the execution.

通常,操作会仅仅是面向实例对象进行实施但是有一些编程语言也支持操作直接面向类来实施类似于前面定义的类变量和实例变量我们也可以定义类操作和实例操作在程序的应用中,类操作通常被用来对类变量进行管理,或者用来创造新的实例.Smalltalk类操作非常普通和常见而在Eiffel,则取消了类操作,因为需要保障明确的区分程序描述和程序执行.

However, every programming language has operations for creating new instances. This can be seen as a class operation as it operates on the class. In Smalltalk, this is not significant, but in Eiffel, it is considered to be an exception. The stimulus is often named new (Smalltalk, C++, Simula and Objective-C) or Create (Eiffel). The stimulus is sent directly to the class, as there will be no instance, as yet, that can receive it. Each class has, therefore, an operation (corresponding to) new or Create, and when the class receives the stimulus, a new instance is created by allocating storage area for the instance and initiating instance variables (set to default values). The operation also makes sure that one of the instance variables, instance Of, refers to the instance's class. Figure 5.7 shows, using Smalltalk/V, Eiffel and a Weizenbaum diagram, how classes are declared with instance variables, how an instance Tom is created, how aPerson is specified to reference Tom and how Tom is made to Jump.

然而,每一种编程语言都有创建新实例的操作,这种操作可以被认为是一种类操作,因为他是直接面向类来操作的.Smalltalk,这种操作显得并不是非常重要,但是在Eiffel,这种操作则被认为是非常有价值的 这种激励通常被命名为new (Smalltalk, C++, Simula and Objective-C) or Create (Eiffel). 创建新实例的激励是直接发送给类对象,因为在创建实例之前,可能还没有实例能够接收激励.所以无论是那一种面向对象的编程语言,每个类,必须拥有一个等效于new 或者Create的操作每当这个类接收到这个激励程序执行将通过分配存储空间的方式来创建一个新的实例,同时完成实例变量的初始化(设置为缺省的取值)   创建实例的操作同时需要保证同步创建一个非常重要的实例变量,也就是instance Of,说用来标识新创建的实例归属于对应的类5-7显示了利用Weizenbaum diagram以及Smalltalk/V, Eiffel语言类是如何伴随实例变量而创建一个实例TOM是如何创建的以及aPerson这个实例变量是如何被定义来索引到TOM, 以及TOM是如何执行操作来JUMP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值