• 关于类的基本认识
    • 编写类

    关于类的基本认识

    在开始部分,请看官非常非常耐心地阅读下面几个枯燥的术语解释,本来这不符合本教程的风格,但是,请看官谅解,因为列位将来一定要阅读枯燥的东西的。这些枯燥的属于解释,均来自维基百科。

    1、问题空间

    问题空间是问题解决者对一个问题所达到的全部认识状态,它是由问题解决者利用问题所包含的信息和已贮存的信息主动地构成的。

    一个问题一般有下面三个方面来定义:

    • 初始状态——一开始时的不完全的信息或令人不满意的状况;
    • 目标状态——你希望获得的信息或状态;
    • 操作——为了从初始状态迈向目标状态,你可能采取的步骤。

    这三个部分加在一起定义了问题空间(problem space)。

    2、对象

    对象(object),台湾译作物件,是面向对象(Object Oriented)中的术语,既表示客观世界问题空间(Namespace)中的某个具体的事物,又表示软件系统解空间中的基本元素。

    对象这个属于,比较抽象。因此,有人认为,将object翻译为“对象”,常常让人迷茫,不如翻译为“物件”更好。因为“物件”让人感到一种具体的东西,而所谓对象,就是指那种具体的东西。

    这种看法在某些语言中是非常适合的。但是,在Python中,则无所谓,不管怎样,python中的一切都是对象,不管是字符串、函数、模块还是类,都是对象。“万物皆对象”。

    都是对象有什么优势吗?太有了。这说明python天生就是OOP的。也说明,python中的所有东西,都能够进行拼凑组合应用,因为对象就是可以拼凑组合应用的。

    对于对象这个东西,OOP大师Grandy Booch的定义,应该是权威的,相关定义的内容包括:

    • 对象:一个对象有自己的状态、行为和唯一的标识;所有相同类型的对象所具有的结构和行为在他们共同的类中被定义。
    • 状态(state):包括这个对象已有的属性(通常是类里面已经定义好的)在加上对象具有的当前属性值(这些属性往往是动态的)
    • 行为(behavior):是指一个对象如何影响外界及被外界影响,表现为对象自身状态的改变和信息的传递。
    • 标识(identity):是指一个对象所具有的区别于所有其它对象的属性。(本质上指内存中所创建的对象的地址)

    3、面向对象

    面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

    面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。

    目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。 此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。反对者在某些领域对此予以否认。

    当我们提到面向对象的时候,它不仅指一种程序设计方法。它更多意义上是一种程序开发方式。在这一方面,我们必须了解更多关于面向对象系统分析和面向对象设计(Object Oriented Design,简称OOD)方面的知识。

    下面再引用一段来自维基百科中关于OOP的历史。

    面向对象程序设计的雏形,早在1960年的Simula语言中即可发现,当时的程序设计领域正面临着一种危机:在软硬件环境逐渐复杂的情况下,软件如何得到良好的维护?面向对象程序设计在某种程度上通过强调可重复性解决了这一问题。20世纪70年代的Smalltalk语言在面向对象方面堪称经典——以至于30年后的今天依然将这一语言视为面向对象语言的基础。

    计算机科学中对象和实例概念的最早萌芽可以追溯到麻省理工学院的PDP-1系统。这一系统大概是最早的基于容量架构(capability based architecture)的实际系统。另外1963年Ivan Sutherland的Sketchpad应用中也蕴含了同样的思想。对象作为编程实体最早是于1960年代由Simula 67语言引入思维。Simula这一语言是奥利-约翰·达尔和克利斯登·奈加特在挪威奥斯陆计算机中心为模拟环境而设计的。(据说,他们是为了模拟船只而设计的这种语言,并且对不同船只间属性的相互影响感兴趣。他们将不同的船只归纳为不同的类,而每一个对象,基于它的类,可以定义它自己的属性和行为。)这种办法是分析式程序的最早概念体现。在分析式程序中,我们将真实世界的对象映射到抽象的对象,这叫做“模拟”。Simula不仅引入了“类”的概念,还应用了实例这一思想——这可能是这些概念的最早应用。

    20世纪70年代施乐PARC研究所发明的Smalltalk语言将面向对象程序设计的概念定义为,在基础运算中,对对象和消息的广泛应用。Smalltalk的创建者深受Simula 67的主要思想影响,但Smalltalk中的对象是完全动态的——它们可以被创建、修改并销毁,这与Simula中的静态对象有所区别。此外,Smalltalk还引入了继承性的思想,它因此一举超越了不可创建实例的程序设计模型和不具备继承性的Simula。此外,Simula 67的思想亦被应用在许多不同的语言,如Lisp、Pascal。

    面向对象程序设计在80年代成为了一种主导思想,这主要应归功于C++——C语言的扩充版。在图形用户界面(GUI)日渐崛起的情况下,面向对象程序设计很好地适应了潮流。GUI和面向对象程序设计的紧密关联在Mac OS X中可见一斑。Mac OS X是由Objective-C语言写成的,这一语言是一个仿Smalltalk的C语言扩充版。面向对象程序设计的思想也使事件处理式的程序设计更加广泛被应用(虽然这一概念并非仅存在于面向对象程序设计)。一种说法是,GUI的引入极大地推动了面向对象程序设计的发展。

    苏黎世联邦理工学院的尼克劳斯·维尔特和他的同事们对抽象数据和模块化程序设计进行了研究。Modula-2将这些都包括了进去,而Oberon则包括了一种特殊的面向对象方法——不同于Smalltalk与C++。

    面向对象的特性也被加入了当时较为流行的语言:Ada、BASIC、Lisp、Fortran、Pascal以及种种。由于这些语言最初并没有面向对象的设计,故而这种糅合常常会导致兼容性和维护性的问题。与之相反的是,“纯正的”面向对象语言却缺乏一些程序员们赖以生存的特性。在这一大环境下,开发新的语言成为了当务之急。作为先行者,Eiffel成功地解决了这些问题,并成为了当时较受欢迎的语言。

    在过去的几年中,Java语言成为了广为应用的语言,除了它与C和C++语法上的近似性。Java的可移植性是它的成功中不可磨灭的一步,因为这一特性,已吸引了庞大的程序员群的投入。

    在最近的计算机语言发展中,一些既支持面向对象程序设计,又支持面向过程程序设计的语言悄然浮出水面。它们中的佼佼者有Python、Ruby等等。

    正如面向过程程序设计使得结构化程序设计的技术得以提升,现代的面向对象程序设计方法使得对设计模式的用途、契约式设计和建模语言(如UML)技术也得到了一定提升。

    列位看官,当您阅读到这句话的时候,我就姑且认为您已经对面向对象有了一个模糊的认识了。那么,类和OOP有什么关系呢?

    维基百科中这样定义了类:

    在面向对象程式设计,类(class)是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。

    类的更严格的定义是由某种特定的元数据所组成的内聚的包。它描述了一些对象的行为规则,而这些对象就被称为该类的实例。类有接口和结构。接口描述了如何通过方法与类及其实例互操作,而结构描述了一个实例中数据如何划分为多个属性。类是与某个层的对象的最具体的类型。类还可以有运行时表示形式(元对象),它为操作与类相关的元数据提供了运行时支持。

    支持类的编程语言在支持与类相关的各种特性方面都多多少少有一些微妙的差异。大多数都支持不同形式的类继承。许多语言还支持提供封装性的特性,比如访问修饰符。类的出现,为面向对象编程的三个最重要的特性(封装性,继承性,多态性),提供了实现的手段。

    看到这里,看官或许有一个认识,要OOP编程,就得用到类。可以这么说,虽然不是很严格。但是,反过来就不能说了。不是说用了类就一定是OOP。

    编写类

    对类的理解,需要看官有一定的抽象思维。因为类(Class)本身所定义的是某事物的抽象特点。例如定义一个类:

    1. class Human: #这是定义类的方法,通常类的名称用首字母大写的单词或者单词拼接
    2. pass

    好,现在就从这里开始,编写一个类,不过这次我们暂时不用python,而是用伪代码,当然,这个代码跟python相去甚远。如下:

    1. class Human:
    2. 四肢
    3. 性格
    4. 爱好
    5. 学习()

    对象(Object)是类的实例。刚才已经定义了一个名字为Human的类,从而定义了世界上所有的Human,但是这是一个抽象的Human,不是具体某个人。而对一个具体的人,他的四肢特点、性格、爱好等都是具体的,这些东西在这里被称之为属性。

    下面就找一个具体的人:王二麻子,把上面的类实例化。

    1. 王二麻子 = Human()
    2. 王二麻子.四肢 = 修长
    3. 王二麻子.爱好 = MM

    在这里,王二麻子就是Human这个类的一个实例。一个具体对象属性的值被称作它的“状态”。(系统给对象分配内存空间,而不会给类分配内存空间,这很好理解,类是抽象的系统不可能给抽象的东西分配空间,对象是具体的)

    行文至此,看官是不是大概对类有了一个模糊的认识了呢?

    鉴于类,距离我们的直观感觉似乎有点远。所以,要慢慢道来。本讲内容不多,盼望看官能理解。