1,类与对象
类,是函数的更高级抽象。它描述的是一类事物具有的普遍特性,而函数则是描述这些普遍特性中的某一个点。
比如说对于车来说,有各种各样的车,车也有各种各样的功能和属性。如果采用函数来抽象,那么如果要完整的抽象一辆车出来,那么会需要很多函数相互配合,当然这其中必定少不了全局变量。采用函数的方式来抽象车的话,会有一个弊端,就是时隔很久之后,你可以记不起来这辆车是由哪些函数和全局变量抽象而来的。
于是面向对象编程,也就是类的出现,解决了这个问题。
类,抽象的是车这一类物体,描述它们的共有属性和功能,然后由该类衍生而来的子类又具有各自特有的属性和功能,同时,在类的定义中,我们把需要描述该类事物所必须的方法(功能)和属性,集中到一个“类”中,这样你永远不会忘记,这辆车是怎么来的。
那么,相对于类而言,对象则是类的一个具体的个体。比如说,车中有自行车,那自行车又有很多中,那你说的这个自行车到底是那一个呢?这就需要一个实实在在的“东西”来表示,在面向对象中,这个“东西”就是对象。也就是说,对象是类的一个实例!
2,创建类
python中,定义一个类,和在PHP中定义一个类一样,都是采用 class 关键字,但是其定义方式确实有些特殊,看下面的例子:
约定俗称的,类的命名,我们采用“驼峰法”并且首字母要大写。
python 中 采用 class 关键字表示要定义一个类,后面的括号中表示这个类是从哪个类继承而来的,通常情况下,要是你找不到一个合适的类继承,那么就继承自最顶层的 object 吧,这倒是和 java 中有些相似。
定义完类之后就是定义类的方法,也就是这个车有哪些功能。类的方法和函数定义没有什么区别,只是在类中,方法要求你必须设置一个 self 参数,而且该参数始终位于方法形参列表的第一个。当然了,形参要求你这么来写,但是在调用的时候你却并不需要手动去传递这个参数。
python 类的实例化和其它编程语言有些不一样,不需要使用 new 关键字,其它的没有区别。
python 中调用类的方法及方法参数的传递,同样和其它编程语言没有区别。
3,访问限制
现在,我们来定义一个比较复杂一点的车类,就像是这样:
现在这个类,它具有了车该有的功能和相应的属性。同样的,我们通过类的对象或者叫做实例,在类的外面可以访问到类对应的属性和其方法。
但是作为一个类,应该具备最基本的封装性,对于属性和一些敏感方法,不应该在类的外面可以直接访问,应该将其私有化。
Python 中并没有提供像PHP中的关于访问权限的关键字,例如 private,它通过在属性或者方法名之前增加一个“双下划线”来标识,该属性或者方法,在类的外部不能够被直接访问,就像是这样:
在以后的python编程中,你会碰到变量名前面带有“单下划线”的变量,那么它的含义是表示该变量虽然可以被外部直接访问,但是最好不要那么做。
当然,对于python中的私有属性或者方法,难道只要带了“双下划线”就一定不可以在类的外部被访问到吗?
其实不是的,对于“私有”属性或者方法,Python只是对它们进行了重命名,这样你直接调用它的时候就会产生找不到的假象,但实际上你是可以访问到的,就像这样:这也是Python重命名的通用规则,在“私有”变量名之前增加“_ClassName”
你看,是不是就访问成功了呢?
实际上,python并不会阻止你在程序中做任何的坏事,相反它对你不作任何的限制,为了就是让所有的责任都让程序员自己来承担,有助于你编写出严谨的程序代码!(总觉得,其实也不那么好 。。。。)
4,设置器与访问器
如果你知道java中的“豆子”这个东西,那么对于设置器和访问器应该就不会陌生,因为这个东西,我头一次听说就是在java中。
它的大概思想是,针对类中的每一个私有的属性,如果想要被类外部的对象能够访问和修改,那么就必须针对这个属性产生两个共有的方法,这样对象就可以调用这两个方法来达到修改和访问私有属性的目的。
由于,这种东西只是一种思想,而并非编程语言的特殊实现,因此在python中也可以轻松的模拟:
在这里,我们把“setColor”和“getColor”方法,分别称作是 Car 类中 私有属性 color 的设置器和访问器。
当然了,安装约定俗成的规定,对于属性的设置器的命名规范是“set”加上它的属性名,同样的访问器就是“get”加上属性名。
其实,上面的案例已经达到了我们想要的效果,那在java中,这就是实现好了。但是在python中却还要再追求一点简单,于是就出现了 “@property”这个东西。
先看一个案例:
这样,对于“私有属性 __color”,可以定义其对应的可以供外部对象调用的方法“color”,在这个“color 方法”上使用了 @property 装饰器之后,这个方法就变成了属性“color”的访问器。如果你还想给属性“color”加一个设置器,那么就可以采用图上的方式。
当采用 @property 的方式实现了属性的访问器和设置器之后,原本的私有属性,在外面就可以自由的以属性的方式访问了!
5,继承,构造方法,多态
经过上面知识的大概说明,对于python的面向对象编程,其实有了一个大概的影像。以一个类的方式,编写一些简单的功能,还是能够实现的。
不过对于OOP而言,继承,绝对是重中之重。所以,下面的案例就演示了 python 中的继承:
python 中的继承,是在定义类的时候在后面的“()”中指定的。
在开始的时候,就说过,在定义 Car 类的时候,如果没有合适的继承类那么就继承自 object 类,因为这个是 python 中所有对象的顶层类。
那现在,我自己定义的 Bicycle 类则是继承自自定义的 Car 类,继承的语法规则就是那样。
代码桩:python 中对于一个空函数,或者空的类,需要使用 pass 来占位。否则会报错!这个大概是为了 python 中没有“{}”而做的补充,当然了,这里可以叫做“代码桩”也可以叫做“占位符”
在讲多态之前,我们先看一下怎么样使用python的构造方法:
python中的构造方法叫:__init__ 好像挺贴切!
对于继承,如果子类也有对应的构造方法,那么就需要显式的调用父类的构造方法,调用父类的构造方法采用的方式和java中倒是有些相像,因此都是用 super 函数实现:
#-*- coding:utf-8 -*-
class Car(object):
__color = None
def __init__(self, color):
self.__color = color
@property
def color(self):
return self.__color
class Bicycle(Car):
__width = None
def __init__(self, width, color):
super(Bicycle, self).__init__(color)
self.__width = width
@property
def width(self):
return self.__width
b = Bicycle(12,"blue")
print b.color
print b.width
多态是OOP编程中的一种设计思想,它是以OOP的继承特性为基础来实现的,这里跟python的基本特性相关不大,而且要描述清楚,还是有些代码要写,限于博文太长,还是先跳过!
6,补充知识
这里涉及到python中的几个魔术方法:
__str__ : 设置类的对象信息
__getattr__ 或者 __getattribute__ :用来设置,当通过对象访问不存在的属性时,调用的方法
__call__ : 可以把对象当做函数来直接调用。感觉用处不大!
-----------------------------------------------下篇写异常--------------------------------------------------
感觉,还是 eclipse+pydev这个开发环境好些,PyCharm,真心感觉有些渣!