python(十)面向对象编程

1,类与对象

类,是函数的更高级抽象。它描述的是一类事物具有的普遍特性,而函数则是描述这些普遍特性中的某一个点。

比如说对于车来说,有各种各样的车,车也有各种各样的功能和属性。如果采用函数来抽象,那么如果要完整的抽象一辆车出来,那么会需要很多函数相互配合,当然这其中必定少不了全局变量。采用函数的方式来抽象车的话,会有一个弊端,就是时隔很久之后,你可以记不起来这辆车是由哪些函数和全局变量抽象而来的。

于是面向对象编程,也就是类的出现,解决了这个问题。

类,抽象的是车这一类物体,描述它们的共有属性和功能,然后由该类衍生而来的子类又具有各自特有的属性和功能,同时,在类的定义中,我们把需要描述该类事物所必须的方法(功能)和属性,集中到一个“类”中,这样你永远不会忘记,这辆车是怎么来的。

那么,相对于类而言,对象则是类的一个具体的个体。比如说,车中有自行车,那自行车又有很多中,那你说的这个自行车到底是那一个呢?这就需要一个实实在在的“东西”来表示,在面向对象中,这个“东西”就是对象。也就是说,对象是类的一个实例!

2,创建类

python中,定义一个类,和在PHP中定义一个类一样,都是采用 class 关键字,但是其定义方式确实有些特殊,看下面的例子:

213628_eA75_1156660.png

约定俗称的,类的命名,我们采用“驼峰法”并且首字母要大写。

python 中 采用 class 关键字表示要定义一个类,后面的括号中表示这个类是从哪个类继承而来的,通常情况下,要是你找不到一个合适的类继承,那么就继承自最顶层的 object 吧,这倒是和 java 中有些相似。

定义完类之后就是定义类的方法,也就是这个车有哪些功能。类的方法和函数定义没有什么区别,只是在类中,方法要求你必须设置一个 self 参数,而且该参数始终位于方法形参列表的第一个。当然了,形参要求你这么来写,但是在调用的时候你却并不需要手动去传递这个参数。

python 类的实例化和其它编程语言有些不一样,不需要使用 new  关键字,其它的没有区别。

python 中调用类的方法及方法参数的传递,同样和其它编程语言没有区别。

3,访问限制

现在,我们来定义一个比较复杂一点的车类,就像是这样:

215106_W1Ho_1156660.png

现在这个类,它具有了车该有的功能和相应的属性。同样的,我们通过类的对象或者叫做实例,在类的外面可以访问到类对应的属性和其方法。

但是作为一个类,应该具备最基本的封装性,对于属性和一些敏感方法,不应该在类的外面可以直接访问,应该将其私有化。

Python  中并没有提供像PHP中的关于访问权限的关键字,例如 private,它通过在属性或者方法名之前增加一个“双下划线”来标识,该属性或者方法,在类的外部不能够被直接访问,就像是这样:

220922_bFcN_1156660.png

在以后的python编程中,你会碰到变量名前面带有“单下划线”的变量,那么它的含义是表示该变量虽然可以被外部直接访问,但是最好不要那么做。

当然,对于python中的私有属性或者方法,难道只要带了“双下划线”就一定不可以在类的外部被访问到吗?

其实不是的,对于“私有”属性或者方法,Python只是对它们进行了重命名,这样你直接调用它的时候就会产生找不到的假象,但实际上你是可以访问到的,就像这样:这也是Python重命名的通用规则,在“私有”变量名之前增加“_ClassName”

221422_Slb5_1156660.png

你看,是不是就访问成功了呢?

实际上,python并不会阻止你在程序中做任何的坏事,相反它对你不作任何的限制,为了就是让所有的责任都让程序员自己来承担,有助于你编写出严谨的程序代码!(总觉得,其实也不那么好 。。。。)

4,设置器与访问器

如果你知道java中的“豆子”这个东西,那么对于设置器和访问器应该就不会陌生,因为这个东西,我头一次听说就是在java中。

它的大概思想是,针对类中的每一个私有的属性,如果想要被类外部的对象能够访问和修改,那么就必须针对这个属性产生两个共有的方法,这样对象就可以调用这两个方法来达到修改和访问私有属性的目的。

由于,这种东西只是一种思想,而并非编程语言的特殊实现,因此在python中也可以轻松的模拟:

131739_ubJG_1156660.png

在这里,我们把“setColor”和“getColor”方法,分别称作是 Car 类中 私有属性 color 的设置器和访问器。

当然了,安装约定俗成的规定,对于属性的设置器的命名规范是“set”加上它的属性名,同样的访问器就是“get”加上属性名。

其实,上面的案例已经达到了我们想要的效果,那在java中,这就是实现好了。但是在python中却还要再追求一点简单,于是就出现了 “@property”这个东西。

先看一个案例:

132508_sPnq_1156660.png

这样,对于“私有属性 __color”,可以定义其对应的可以供外部对象调用的方法“color”,在这个“color 方法”上使用了 @property 装饰器之后,这个方法就变成了属性“color”的访问器。如果你还想给属性“color”加一个设置器,那么就可以采用图上的方式。

当采用 @property 的方式实现了属性的访问器和设置器之后,原本的私有属性,在外面就可以自由的以属性的方式访问了!

5,继承,构造方法,多态

经过上面知识的大概说明,对于python的面向对象编程,其实有了一个大概的影像。以一个类的方式,编写一些简单的功能,还是能够实现的。

不过对于OOP而言,继承,绝对是重中之重。所以,下面的案例就演示了 python 中的继承:

135526_Ia1n_1156660.png

python 中的继承,是在定义类的时候在后面的“()”中指定的。

在开始的时候,就说过,在定义 Car 类的时候,如果没有合适的继承类那么就继承自 object 类,因为这个是 python 中所有对象的顶层类。

那现在,我自己定义的  Bicycle 类则是继承自自定义的  Car 类,继承的语法规则就是那样。

代码桩:python 中对于一个空函数,或者空的类,需要使用 pass 来占位。否则会报错!这个大概是为了 python 中没有“{}”而做的补充,当然了,这里可以叫做“代码桩”也可以叫做“占位符”

在讲多态之前,我们先看一下怎么样使用python的构造方法:

141738_ejWu_1156660.png

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__ : 设置类的对象信息

144105_qZpv_1156660.png

__getattr__ 或者 __getattribute__ :用来设置,当通过对象访问不存在的属性时,调用的方法

144642_MWBl_1156660.png

__call__ : 可以把对象当做函数来直接调用。感觉用处不大!

-----------------------------------------------下篇写异常--------------------------------------------------

感觉,还是 eclipse+pydev这个开发环境好些,PyCharm,真心感觉有些渣!


转载于:https://my.oschina.net/u/1156660/blog/371985

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值