《Python面向对象程序设计ppt课件.ppt》由会员分享,可在线阅读,更多相关《Python面向对象程序设计ppt课件.ppt(40页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、面向对象程序设计(Object Oriented Programming,OOP)的思想主要针对大型软件设计而提出,使得软件设计更加灵活,能够很好地支持代码复用和设计复用,并且使得代码具有更好的可读性和可扩展性。面向对象程序设计的一条基本原则是计算机程序由多个能够起到子程序作用的单元或对象组合而成,这大大地降低了软件开发的难度,使得编程就像搭积木一样简单。面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类,面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系。
2、Python完全采用了面向对象程序设计的思想,是真正面向对象的高级动态编程语言,完全支持面向对象的基本功能,如封装、继承、多态以及对基类方法的覆盖或重写。但与其他面向对象程序设计语言不同的是,Python中对象的概念很广泛,Python中的一切内容都可以称为对象例如,字符串、列表、字典、元组等内置数据类型都具有和类完全相似的语法和用法。创建类时用变量形式表示的对象属性称为数据成员或成员属性,用函数形式表示的对象行为称为成员函数或成员方法,成员属性和成员方法统称为类的成员。Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类
3、的内部实现。类名的首字母一般要大写,当然您也可以按照自己的习惯定义类名,但是一般推荐参考惯例来命名,并在整个系统的设计和实现中保持风格一致,这一点对于团队合作尤其重要。例如:class Car: #新式类必须有至少一个基类 def infor(self): print( This is a car ) 定义了类之后,可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法,例如下面的代码: car = Car() car.infor() This is a car在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例,下面的代码演示了i
4、sinstance()的用法。 isinstance(car, Car)True isinstance(car, str)False最后,Python提供了一个关键字“pass”,类似于空语句,可以用在类和函数的定义中或者选择结构中。当暂时没有确定如何实现功能,或者为以后的软件升级预留空间,或者其他类型功能时,可以使用该关键字来“占位”。例如下面的代码都是合法: class A: pass def demo(): pass if 53: pass6.1.2 self参数类的所有实例方法都必须至少有一个名为“self”的参数,并且必须是方法的第一个形参(如果有多个形参的话),“self”参数代表
5、将来要创建的对象本身。在类的实例方法中访问实例属性时需要以“self”为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数,如果在外部通过类名调用对象方法则需要显式为self参数传值。在Python中,在类中定义实例方法时将第一个参数定义为“self”只是一个习惯,而实际上类的实例方法中第一个参数的名字是可以变化的,而不必须使用“self”这个名字,例如下面的代码: class A: def _init_(hahaha, v): hahaha.value = v def show(hahaha): print(hahaha.value) a = A(3) a.show()36.1.3
6、类成员与实例成员这里主要指数据成员,或者广义上的属性。可以说属性有两种,一种是实例属性,另一种是类属性。实例属性一般是指在构造函数_init_()中定义的,定义和使用时必须以self作为前缀;类属性是在类中所有方法之外定义的数据成员。在主程序中(或类的外部),实例属性属于实例(对象),只能通过对象名访问;而类属性属于类,可以通过类名或对象名访问。n在类的方法中可以调用类本身的其他方法,也可以访问类属性以及对象属性。在Python中比较特殊的是,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计语言不同的,也是Python动态类型特点的一种重要体现。class Car: price =
7、 100000 #定义类属性 def _init_(self, c): self.color = c #定义实例属性car1 = Car(Red)car2 = Car(Blue)print(car1.color, Car.price)Car.price = 110000 #修改类属性Car.name = QQ #增加类属性car1.color = Yellow #修改实例属性print(car2.color, Car.price, Car.name)print(car1.color, Car.price, Car.name)def setSpeed(self, s): self.speed =
8、 scar1.setSpeed = types.MethodType(setSpeed, Car) #动态为对象增加成员方法car1.setSpeed(50) #调用对象的成员方法print(car1.speed)n在Python中,函数和方法是有区别的。方法一般指与特定实例绑定的函数,通过对象调用方法时,对象本身将被作为第一个参数传递过去,普通函数并不具备这个特点。 class Demo:pass t = Demo() def test(self, v):self.value = v t.test = test t.test t.test(t, 3) print(t.value)3 t.te
9、st = types.MethodType(test, t) t.testbound method test of t.test(5) print(t.value)56.1.4 私有成员与公有成员Python并没有对私有成员提供严格的访问保护机制。在定义类的属性时,如果属性名以两个下划线“_”开头则表示是私有属性,否则是公有属性。私有属性在类的外部不能直接访问,需要通过调用对象的公有成员方法来访问,或者通过Python支持的特殊方式来访问。Python提供了访问私有属性的特殊方式,可用于程序的测试和调试,对于成员方法也具有同样的性质。私有属性是为了数据封装和保密而设的属性,一般只能在类的成员方
10、法(类的内部)中使用访问,虽然Python支持一种特殊的方式来从外部直接访问类的私有成员,但是并不推荐您这样做。公有属性是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中使用。6.1.4 私有成员与公有成员 class A: def _init_(self, value1 = 0, value2 = 0):self._value1 = value1self._value2 = value2 def setValue(self, value1, value2):self._value1 = value1self._value2 = value2 def show(self):prin
11、t(self._value1)print(self._value2) a = A() a._value10 a._A_value2 #在外部访问对象的私有数据成员06.1.4 私有成员与公有成员在IDLE环境中,在对象或类名后面加上一个圆点“.”,稍等一秒钟则会自动列出其所有公开成员,模块也具有同样的特点。而如果在圆点“.”后面再加一个下划线,则会列出该对象或类的所有成员,包括私有成员。在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。用下划线作为变量名和方法名前缀和后缀来表示类的特殊成员:_xxx:这样的对象叫做保护成员,不能用from module impor
12、t *导入,只有类对象和子类对象能访问这些成员;_xxx_:系统定义的特殊成员;_xxx:类中的私有成员,只有类对象自己能访问,子类对象也不能访问到这个成员,但在对象外部可以通过“对象名._类名_xxx”这样的特殊方式来访问。Python中不存在严格意义上的私有成员。n另外,在IDLE交互模式下,一个下划线“_”表示解释器中最后一次显示的内容或最后一次语句正确执行的输出结果。例如: 3 + 58 _ + 210 _ * 330 _ / 56 33 1/0Traceback (most recent call last): File , line 1, in 1/0ZeroDivisionErr
13、or: integer division or modulo by zero _36.1.4 私有成员与公有成员 class Fruit: def _init_(self): self._color = Red self.price = 1 apple = Fruit() apple.price #显示对象公开数据成员的值1 apple.price = 2 #修改对象公开数据成员的值 apple.price2 print(apple.price, apple._Fruit_color) #显示对象私有数据成员的值2 Red apple._Fruit_color = Blue #修改对象私有数据
14、成员的值 print(apple.price, apple._Fruit_color)2 Blue print(apple._color) #不能直接访问对象的私有数据成员,出错AttributeError: Fruit instance has no attribute _color6.2 方法在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。其中,公有方法、私有方法都属于对象,私有方法的名字以两个下划线“_”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象
15、的方法中通过“self”调用或在外部通过Python支持的特殊方式来调用。如果通过类名来调用属于对象的公有方法,需要显式为该方法的“self”参数传递一个对象名,用来明确指定访问哪个对象的数据成员。静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。一般将“cls”作为类方法的第一个参数名称,但也可以使用其他的名字作为参数,并且在调用类方法时不需要为该参数传递值。6.2 方法 r = Root(3) r.classShowTotal() #通过对象来调用类方法1 r.staticShowTotal() #通过对象来调用静态方法1 r.show()se
16、lf._value: 3Root._total: 1 rr = Root(5) Root.classShowTotal() #通过类名调用类方法2 Root.staticShowTotal() #通过类名调用静态方法26.2 方法 Root.show() #试图通过类名直接调用实例方法,失败TypeError: unbound method show() must be called with Root instance as first argument (got nothing instead) Root.show(r) #但是可以通过这种方法来调用方法并访问实例成员self._value
17、: 3Root._total: 2 r.show()self._value: 3Root._total: 2 Root.show(rr) #通过类名调用实例方法时为self参数显式传递对象名self._value: 5Root._total: 2 rr.show()self._value: 5Root._total: 26.3 属性Python 2.x和Python 3.x对属性的实现和处理方式不一样,内部实现有较大的差异,使用时应注意二者之间的区别。6.3.2 Python 3.x中的属性在Python 3.x中,属性得到了较为完整的实现,支持更加全面的保护机制。例如下面的代码所示,如果设置
18、属性为只读,则无法修改其值,也无法为对象增加与属性同名的新成员,同时,也无法删除对象属性。6.3.2 Python 3.x中的属性 class Test: def _init_(self, value):self._value = value property def value(self): #只读,无法修改和删除return self._value t = Test(3) t.value3 t.value = 5 #只读属性不允许修改值AttributeError: cant set attribute t.v=5 #动态增加新成员 t.v5 del t.v #动态删除成员 del t.v
19、alue #试图删除对象属性,失败AttributeError: cant delete attribute t.value3下面的代码则把属性设置为可读、可修改,而不允许删除。 class Test: def _init_(self, value):self._value = value def _get(self):return self._value def _set(self, v):self._value = v value = property(_get, _set) def show(self):print(self._value) t = Test(3) t.value #允许
20、读取属性值3 t.value = 5 #允许修改属性值 t.value5 t.show() #属性对应的私有变量也得到了相应的修改5 del t.value #试图删除属性,失败AttributeError: cant delete attribute也可以将属性设置为可读、可修改、可删除。 class Test: def _init_(self, value):self._value = value def _get(self):return self._value def _set(self, v):self._value = v def _del(self):del self._valu
21、e value = property(_get, _set, _del) def show(self):print(self._value)6.3.2 Python 3.x中的属性 t = Test(3) t.show()3 t.value3 t.value = 5 t.show()5 t.value5 del t.value t.valueAttributeError: Test object has no attribute _Test_value t.show()AttributeError: Test object has no attribute _Test_value t.valu
22、e =1 #为对象动态增加属性和对应的私有数据成员 t.show()1 t.value16.4.1 常用特殊方法Python类有大量的特殊方法,其中比较常见的是构造函数和析构函数。Python中类的构造函数是_init_(),一般用来为数据成员设置初值或进行其他必要的初始化工作,在创建对象时被自动调用和执行,可以通过为构造函数定义默认值参数来实现类似于其他语言中构造函数重载的目的。如果用户没有设计构造函数,Python将提供一个默认的构造函数用来进行必要的初始化工作。Python中类的析构函数是_del_(),一般用来释放对象占用的资源,在Python删除对象和收回对象空间时被自动调用和执行。
23、如果用户没有编写析构函数,Python将提供一个默认的析构函数进行必要的清理工作。方法功能说明_init_()构造函数,生成对象时调用_del_()析构函数,释放对象时调用_add_()+_sub_()-_mul_()*_div_()_、truediv_()/_floordiv_()整除_mod_()%_pow_()*_cmp_()比较运算_repr_()打印、转换_setitem_()按照索引赋值_getitem_()按照索引获取值_len_()计算长度_call_()函数调用_contains_ ()测试是否包含某个元素_eq_()、 _ne_()、_lt_()、 _le_()、_gt_(
24、)=、!=、_str_()转化为字符串_lshift_() import MyArray a = MyArray.MyArray(1, 2, 3, 4, 5, 6) b = MyArray.MyArray(6, 5, 4, 3, 2, 1) len(a)6 a.dot(b)56 a a bFalse a = aTrue 3 in aTrue a * 33, 6, 9, 12, 15, 18 a + 23, 4, 5, 6, 7, 8 a * 21, 4, 9, 16, 25, 36 a / 20.5, 1.0, 1.5, 2.0, 2.5, 3.0 a1, 2, 3, 4, 5, 6 a0 =
25、 8 a8, 2, 3, 4, 5, 66.5 继承机制继承是为代码复用和设计复用而设计的,是面向对象程序设计的重要特性之一。当我们设计一个新类时,如果可以继承一个已有的设计良好的类然后进行二次开发,无疑会大幅度减少开发工作量。在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类。派生类可以继承父类的公有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。Python支持多继承,如果父类中有相同的方法名,而在子类中使用时没有指定父类名,则Python解释器将从左向右按顺序进行搜索
26、。6.5 继承机制例1:设计Person类,并根据Person派生Teacher类,分别创建Person类与Teacher类的对象。import typesclass Person(object): #基类必须继承于object,否则在派生类中将无法使用super()函数 def _init_(self, name = , age = 20, sex = man): self.setName(name) self.setAge(age) self.setSex(sex) def setName(self, name): if type(name) != types.StringType: pr
27、int name must be string. return self._name = name def setAge(self, age): if type(age) != types.IntType: print age must be integer. return self._age = age def setSex(self, sex): if sex != man and sex != woman: print sex must be man or woman return self._sex = sex def show(self): print self._name prin
28、t self._age print self._sex6.5 继承机制class Teacher(Person): def _init_(self, name=, age = 30, sex = man, department = Computer): #调用基类构造方法初始化基类的私有数据成员 super(Teacher, self)._init_(name, age, sex) #Person._init_(self, name, age, sex) #也可以这样初始化基类的私有数据成员 self.setDepartment(department) #初始化派生类的数据成员 def set
29、Department(self, department): if type(department) != types.StringType: print department must be a string. return self._department = department def show(self): super(Teacher, self).show() print self._department6.5 继承机制if _name_ =_main_: zhangsan = Person(Zhang San, 19, man) zhangsan.show() lisi = Tea
30、cher(Li Si, 32, man, Math)lisi.show() lisi.setAge(40) #调用继承的方法修改年龄 lisi.show()n为了更好地理解Python类的继承机制,我们来看下面的Python 2.7.11代码,请认真体会构造函数、私有方法以及普通公开方法的继承原理。 class A(): def _init_(self): self._private() self.public() def _private(self): print _private() method of A def public(self): print public() method o
31、f A class B(A): def _private(self): print _private() method of B def public(self): print public() method of B6.5 继承机制 b = B() #自动调用从基类A继承的构造函数_private() method of Apublic() method of B print n.join(dir(b) #查看对象b的成员_A_private_B_private_doc_init_module_Public6.5 继承机制 class C(A): def _init_(self):self._private()self.public() def _private(self):print _private() method of C def public(self):print public() method of C c = C() #自动调用派生类自己的构造函数_private() method of Cpublic() method of C print n.join(dir(c)_A_private_C_private_doc_init_module_public
限制150内