资源简介 (共94张PPT)第8章 面向对象程序设计Chap8 Object-orientedThere is a road in the mountains of books, and diligence is the path面向对象2fp.read()','.join(['Amy', 'John', 'Tom'])这些都是面向对象程序设计的形式面向对象程序设计基本概念8.13程序设计范式(paradim)4面向过程程序设计面向对象程序设计函数式设计逻辑式程序设计面向对象程序设计8.158.1.1 面向对象程序设计6面向对象程序设计对象(实例)由数据及能对其实施的操作所构成的封装体类类描述了对象的特征(数据和操作)7面向对象程序设计8面向对象程序设计:以数据为中心的程序设计方式隐藏数据细节更接近自然思考方式面向过程程序设计:以功能为中心的程序设计方式需要数据细节面向对象程序设计9[4, 2, 7, -1, 3]构建了一个列表对象,x是对其的引用,由于列表对象允许使用sort()方法进行排序,因此通过x.sort()的调用将x引用的对象进行排序>>> x = [4, 2, 7, -1, 3]>>> x.sort()>>> x[-1, 2, 3, 4, 7]8.1.2 面向对象程序设计的基本特征10封装抽象多态继承面向对象程序设计面向对象程序设计(OOP)EncapsulationPolymorphismInheritanceAbstraction面向对象程序设计的基本特征抽象(Abstraction)与封装(Encapsulation)抽象是指对现实世界问题和实体的本质表现;问题分解成数据和数据上的操作封装是将程序具体的实现细节进行隐藏的一种机制抽象是抽取现实问题和实体的本质,封装是将这些本质包装起来进行内部实现12AbstractionEncapsulation面向对象程序设计的基本特征继承(Inheritance)新创建的类的一些特征(包括属性和方法)可以从其他已有的类获得子类继承父类的所有属性和方法,允许修改或添加其他的特征,父类保持不变提高程序设计的代码复用性13Inheritance面向对象程序设计的基本特征多态(Polymorphism)与绑定(Binding)多态指一个事物有多种不同的解释,根据传递参数的不同执行不同的函数或操作不同的代码绑定是指在具体某次使用多态元素时确定使用的是哪一种形式14PolymorphismBinding类与对象8.215类与对象类是对象的特征抽象对象是类的具体化168.2.1 类17类的定义和方法118ClassName, 类的名称类文档字符串,提供查询时的帮助信息13312class ClassName:'''类文档字符串'''类体File2类体, 需要缩进,定义一些类的属性和方法19类的定义和方法120class Dog:'''define Dog class'''def greet(self):print('Hi')Fileclass MyDate:'''this is a very simple example class'''passFile如果类中没有任何属性和方法,仅作为名称空间使用,类体可以用pass语句表示类的定义和方法221父类, 可选,指定从某个已定义的类继承11class ClassName(object):'''类文档字符串'''类体File2object,万类之源2类的定义与方法222定义类的属性定义类的函数(方法)class Dog(object):'''define Dog class'''counter = 0def greet(self):print('Hi')FileInput and Output>>> Dog.counter02324例8-1 学院人员信息类人员的信息包括姓名、年龄可以通过方法增删改和输出人员信息25File# Filename: Prog8-1.pyclass PersonInfo:'''define PersonInfo Class'''def person(self, dep):self.dep = depself.num = 0self.plist = []例8-1 学院人员信息处理添加方法26File# Filename: Prog8-1.pyclass PersonInfo:'''define PersonInfo Class'''def person(self, dep):…def insertp(self, name, age):for x in self.plist:if name in x:print("{0} already in list".format(name))return Falseself.num += 1([name,age])return True例8-1 学院人员信息处理删除方法27File# Filename: Prog8-1.pyclass PersonInfo:'''define PersonInfo Class'''def person(self, dep):…def delp(self, name):for x in self.plist:if name in x:print("Delete {0}".format(name))self.plist.remove(x)self.num -= 1return Trueprint("{0} not in list".format(name))return False例8-1 学院人员信息处理查询方法28File# Filename: Prog8-1.pyclass PersonInfo:'''define PersonInfo Class'''def person(self, dep):…def searchp(self, name):for x in self.plist:if name in x:print("{0} in list".format(name))print(x)return Trueprint("{0} not in list".format(name))return False例8-1 学院人员信息处理输出方法29File# Filename: Prog8-1.pyclass PersonInfo:'''define PersonInfo Class'''def person(self, dep):…def insertp(self, name, age):…def delp(self, name):…def searchp(self, name):…def printplist(self):for x in self.plist:print(x)8.2.2 实例30实例类实例化的形式如下创建实例后,可以使用实例调用方法类方法的第一个参数总是self,指向实例本身>>> x = Dog()>>> x.greet()Hi31变量 = 类名(<参数>)3233实例34Python自动将对象x作为第一个参数传入方法中# Filename: Prog8-2.pyclass Dog(object):"define Dog class"def setName(self, name):self.name = namedef greet(self):print('Hi')if __name__ == '__main__':dog = Dog()dog.setName("Paul")print(dog.name)File例8-2 人员信息类的运用35There are 3 people in Dep.CS['WangTian', 18]['ZhangWei', 20]['LiJianGuo', 40]ZhangWei in list['ZhangWei', 20]Delete LiJianGuo['WangTian', 18]['ZhangWei', 20]Input and Output# Filename: Prog8-3.py#类定义见例8.1if __name__ == '__main__':cs = PersonInfo()cs.person('CS')cs.insertp('WangTian', 18)cs.insertp('ZhangWei', 20)cs.insertp('LiJianGuo', 40)print("There are {0} people in Dep.{1}".format(cs.num,cs.dep))cs.printplist()cs.searchp('ZhangWei')cs.delp('LiJianGuo')cs.printplist()File8.2.3 __init__()与__del__()方法36__init__() 方法__init__()方法永远会在对象创建完成后被Python自动调用和其他方法一样,实例对象本身会作为self参数传递是在对象创建后被Python自动调用的第一个方法37# Filename: Prog8-4.pyclass Dog(object):'''define Dog Class'''def __init__(self, name):self.name = namedef greet(self):print('Hi')if __name__ == '__main__':dog = Dog("Paul")print(dog.name)File当类实例化时, Python 第一步是创建实例对象,然后检查该类是否实现了_init_( )方法,如果实现了,则 Python 将调用_init_( )方法,并且将实例对象作为_init_( )方法的第一个参数(self)传递进去,其他参数由类实例化时给出(类似于函数调用)。因此,_init_( )方法是 Python 创建实例以后自动调用的第一个方法。38__init__() 方法调用的时机39__init__()举例40# Filename: Prog8-5.pyclass PersonInfo:'''define PersonInfo Class'''def __init__(self, dep): #将person()方法改写成__init__()方法self.dep = depself.num = 0self.plist = []…… # 其他代码与例8.1一样if __name__ == '__main__':cs = PersonInfo('CS')…… #其他代码及运行结果与例8.2一样File例8.3 使用__init__()方法改写例8.1中定义的人员信息类。__del__()方法41在使用完对象以后,可以回收对象。Python具有垃圾对象回收机制,当某个实例对象所有的引用都被清除后,实例将自动被释放。在实例释放之前, Python有一个提供特殊处理功能的_del_( )方法,就是C++/ Java 语言中“解构器”的作用。的调用需要通过使用“del变量”来完成。例如: __del__()方法当引用计数减少到0的时候,Python会自动释放对象程序执行退出或者显式调用del都会减少引用计数在Python自动释放对象之前最后一个调用的方法42>>> class Test:def __init__(self):print("initialized")def __del__(self):print("deleted")>>> x = Test()initialized>>> y = x>>> z = y>>> del x>>> del y>>> del zDeletedSource__del__()方法在上述例子中,先创建了一个 Test 类的实例对象,然后调用_init_( )方法输出“initialized”,变量x则是该实例对象的引用。接下来y、z都引用了该实例对象,如下页图8-3(a),因此查看x、y、z引用对象的id是完全一样的。del删除变量x,使得实例对象的引用计数减1,如图8-3(b);del删除变量y,效果与删除变量y一样,如图8-3(c);当del删除变量z后,实例对象的引用计数为0,此时调用_del_( )方法输出“ deleted ”,并且清除实例对象。43引用计数 图8-344Test 实例对象xyzTest 实例对象yzTest 实例对象z引用计数: 3引用计数: 2引用计数: 1del xdel ydel z引用计数为0__del__()被调用自动释放对象由于Python能自动回收无引用的对象,所以在实际应用中,除非在回收的时候需要做特殊的处理,很少需要自己去实现_del_( )。8.2.4 实例属性与类属性45在的介绍中, Python可以在定义类时指定如何对实例的属性赋值。例如,在_init_( )方法中通过 self 设置实例的属性值。事实上, Python 也可以在实例创建以后任意时间设置实例属性,“运行时”也可以创建实例属性,这也是Python类的优秀特性之一。例如中Dog类的setName()方法设置了实例属性name的值,也可以在创建了实例对象以后进行。例如:46实例属性(Instance Attributes)实例属性创建时间: 实例创建时或者实例创建之后所有实例属性保存在名为__dict__的内嵌属性里47>>> class Date:pass>>> curDate = Date()>>> curDate.month = 6>>> curDate.day = 1>>> curDate.__dict__{'day': 1, 'month': 6}Source实例属性48class Dog(object):"define Dog class"def setName(self, name):self.name = namedef greet(self):print(“Hi, I am called %s.".format(self.name))if __name__ == '__main__':dog = Dog()dog.setName("Paul")dog.greet()FileOutput:Hi, I am called Paul.49类属性(Class Attributes)类的数据属性(静态成员)仅仅是所定义的类的变量在类创建后被使用可以由类中的方法来更新,也可以在主程序中更新类属性和实例无关,修改类属性需要使用类名通常用来保存和类相关的值,例如对象计数器50类属性应用举例51# Filename: Prog8-7.pyclass Dog(object):'''define Dog class'''counter = 0def __init__(self, name):self.name = nameDog.counter += 1def greet(self):print("Hi, I am {:s}, my number is {:d}".format(self.name, Dog.counter))if __name__ == '__main__':dog1 = Dog("Zara")dog1.greet()dog2 = Dog("Paul")dog2.greet()FileInput and OutputHi, I am Zara, my number is 1Hi, I am Paul, my number is 2类属性counter被用作追踪已创建实例的计数器上例中,在创建了Dog类的两个实例时,都修改了Dog. counter这个类属性的值。类属性通常用来跟踪与类相关的值,常见的应用有对象计数器。实例属性是针对每个实例所特有的数据,在使用时不应该将与具体实例相关的数据设置为类属性。例如:52535455继承8.3565758父类(基类)子类(派生类)59继承Inheritance继承的原则60is-ahas a更为具体和细化的特例包含已有的类的数据、方法以按钮(Button)为例Quit按钮…………61labelsizeposFontSetLabelSetDefaultEnable8.3.1 子类的创建与继承626364子类的定义单继承多继承65class SubClassName (ParentClass1[, ParentClass2, ...]):' ' '类文档字符串' ' '类体66在子类定义时,如果父类只有一个,继承关系为单继承;如果父类有多个,继承关系则为多继承。Python 支持多继承。多继承功能更为强大,但使用时如果不加以小心,会带来意料不到的问题。本节仅介绍单继承。子类定义好之后,就可以继承父类的特征,也可以增加自己的属性和方法。例如:子类的定义67# Filename: Prog8-9.pyclass Dog(object):'''define Dog class'''counter = 0def __init__(self, name):self.name = nameDog.counter += 1def greet(self):print("Hi, I am {:s}, my number is {:d}".format(self.name, Dog.counter))Fileclass BarkingDog(Dog):"define subclass BarkingDog"def bark(self):print("barking")if __name__ == '__main__':dog = BarkingDog("Zoe")dog.greet()dog.bark()68本例定义了一个子类BarkingDog,它的父类是Dog。BarkingDog类可以继承Dog类的所有方法和属性,并且它也有自己的方法bark( )。Dog是BarkingDog类的一个实例的引用,BarkingDog类中并未定义自己的_init_( )方法,而是继承了父类的,因此 Dog 自动调用了父类的_init_( )方法,其中也使用了父类 Dog 的类属性 counter,之后又调用父类的greet( )方法和子类中定义的bark( )方法。可以看到,通过继承,不用增加任何代码就可获得一些基本操作的实现,提高了开发的效率。8.3.2 重载69重载(overriding)重载:子类改写父类的方法,从而部分地改变父类的行为包括运算符、构造器在内的方法都可以被重载重载父类方法的时候,父类方法中定义的操作不会被自动调用70子类定义举例和重载class BarkingDog (Dog):"define subclass BarkingDog"def greet(self):"initial subclass"print("Woof! I am {:s}, my number is {:d}".format(self.name, Dog.counter))if __name__ == '__main__':dog = BarkingDog("Zoe")dog.greet()71# Filename: Prog8-10.pyclass Dog(object):"define Dog class“counter = 0def __init__(self, name):self.name = nameDog.counter += 1def greet(self):print("Hi, I am {:s}, my number is {:d}".format(self.name, Dog.counter))File727374757677788.3.3 访问控制79访问控制默认情况下,Python 类的成员属性与方法都是“public”提供“访问控制符”来限定成员函数的访问双下划线(__)__var属性会被__classname_var替换,将防止父类与子类中的同名冲突单下划线(_)在属性名前使用一个单下划线字符,防止模块的属性用“from mymodule import *”来加载8081访问控制82>>> class P:def __init__(self, name):self.__name = name>>> x = P('John')>>> x.__nameTraceback (most recent call last):File "", line 1, in x.__nameAttributeError: 'P' object has no attribute '__name'Source为什么出错?怎么解决?8384*常用类和实例相关内建函数8.485常用类和实例相关内建函数86issubclass(classa, classb)isinstance(obj, classn)super(type, obj = None)hasattr(obj, attr)setattr(obj, attr, val)getattr(obj,attr[,default])delattr(obj, attr)vars(obj = None)dir(obj = None)87888990919293小结面向对象程序设计基本概念面向对象程序设计的特征类与对象继承常用类和实例相关内建函数94 展开更多...... 收起↑ 资源预览