零基础学Python:类(1)

类,这个词如果是你第一次听到,把它作为一个单独的名词,总感觉怪怪的,因为在汉语体系中,很常见的是说“鸟类”、“人类”等词语,而单独说“类”,总感觉前面缺点修饰成分。其实,它对应的是英文单词class,“类”是这个class翻译过来的,你就把它作为一个翻译术语吧。

除了“类”这个术语,从现在开始,还要经常提到一个OOP,即面向对象编程(或者“面向对象程序设计”)。

为了理解类和OOP,需要对一些枯燥的名词有了解。

术语

必须了解这些术语的基本含义,因为后面经常用到。下面的术语定义均来自维基百科。

问题空间

定义:

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

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

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

对象

定义:

把object翻译为“对象”,是比较抽象的。因此,有人认为,不如翻译为“物件”更好。因为“物件”让人感到一种具体的东西。

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

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

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

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

大师的话的确有水平,听起来非常高深。不过,初学者可能理解起来就有点麻烦了。我就把大师的话化简一下,但是化简了之后可能在严谨性上就不足了,我想对于初学者来讲,应该是影响不很大的。随着学习和时间的深入,就更能理解大师的严谨描述了。

简化之,对象应该具有属性(就是上面的状态,因为属性更常用)、方法(就是上面的行为,方法跟常被使用)和标识。因为标识是内存中自动完成的,所以,平时不用怎么管理它。主要就是属性和方法。

为了体现“深入浅出”的道理,还是讲故事吧。

既然万物都是对象,那么,某个具体的人也是对象,这是当然的事情。假设这个具体的人就是德艺双馨的苍老师,她是一个对象。这个苍老师具有哪些特征呢?我错了,写到这里发现不能用苍老师为对象的例子,因为容易让读者不专心学习了。我换一个吧,以某个王美女为对象说明(这个王美女完全是虚构的,请不要对号入座,更不要想入非非,如果雷同,纯属巧合)。

王美女这个对象具有某些特征,眼睛,大;腿,长;皮肤,白。当然,既然是美女,肯定还有别的显明特征,读者可以自己假设去。如果用“对象”的术语来说明,就说这些特征都是她的属性。也就是说属性是一个对象做具有的特征,或曰:是什么。

王美女除了具有上面的特征之外,她还能做一些事情,比如她能唱歌、会吹拉弹唱等。这些都是她能够做的事情。用“对象”的术语来说,就是她的“方法”。即方法就是对象能够做什么

任何一个对象都要包括这两部分:属性(是什么)和方法(能做什么)。

面向对象

定义:

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

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

定义:

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

编写类

首先要明确,类是对某一群具有同样属性和方法的对象的抽象。比如这个世界上有很多长翅膀并且会飞的生物,于是聪明的人们就将它们统一称为“鸟”——这就是一个类,虽然它也可以称作“鸟类”。

还是以美女为例子,因为这个例子不仅能阅读本课程不犯困,还能兴趣昂然。

要定义类,就要抽象,找出共同的方面。

class 美女:        #用class来声明,后面定义的是一个类
    pass

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

class 美女:
    胸围 = 90
    腰围 = 58
    臀围 = 83
    皮肤 = white
    唱歌()
    做饭()

定义了一个名称为“美女”的类,其中我约定,没有括号的是属性,带有括号的是方法。这个类仅仅是对美女的通常抽象,并不是某个具体美女.

对于一个具体的美女,比如前面提到的苍老师或者王美女,她们都是上面所定义的“美女”那个类的具体化,这在编程中称为“美女类”的实例。

王美女 = 美女()

我用这样一种表达方式,就是将“美女类”实例化了,对“王美女”这个实例,就可以具体化一些属性,比如胸围;还可以具体实施一些方法,比如做饭。通常可以用这样一种方式表示:

a = 王美女.胸围

用点号.的方式,表示王美女胸围的属性,得到的变量a就是90.另外,还可以通过这种方式给属性赋值,比如

王美女.皮肤 = black

这样,这个实例(王美女)的皮肤就是黑色的了。

通过实例,也可以访问某个方法,比如:

王美女.做饭()

这就是在执行一个方法,让王美女这个实例做饭。现在也比较好理解了,只有一个具体的实例才能做饭。

至此,你是否对类和实例,类的属性和方法有初步理解了呢?如果没有理解,请用苍老师实例化美女类,你一定能理解的。