第6章 面向对象程序设计_第1页
第6章 面向对象程序设计_第2页
第6章 面向对象程序设计_第3页
第6章 面向对象程序设计_第4页
第6章 面向对象程序设计_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章面向对象程序设计主讲夏敏捷计算机学院副教授对象和类对象和类对象的属性、方法和事件6.1面向对象程序设计基础现实生活中的每一个相对独立的事物都可以看做一个对象,例如,一个人,一辆车,一台电脑等。对象是具有某些特性和功能的具体事物的抽象。每个对象都具有描述其特征的属性及附属于它的行为。面向对象程序设计是一种计算机编程架构,它具有以下3个基本特性。(1)封装性(Encapsulation)(2)继承性(Inheritance)(3)多态性(Polymorphism)Python完全采用了面向对象程序设计的思想,是真正面向对象的高级动态编程语言,完全支持面向对象的基本功能,如封装、继承、多态以及对基类方法的覆盖或重写。但与其他面向对象程序设计语言不同的是,Python中对象的概念很广泛,Python中的一切内容都可以称为对象,而不一定必须是某个类的实例。例如,字符串、列表、字典、元组等内置数据类型都具有和类完全相似的语法和用法。创建类时用变量形式表示的对象属性称为数据成员或成员属性,用函数形式表示的对象行为称为成员函数或成员方法,成员属性和成员方法统称为类的成员。6.2类和对象面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类,面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系。6.2.1类定义语法Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。类名的首字母一般要大写,当然您也可以按照自己的习惯定义类名,但是一般推荐参考惯例来命名,并在整个系统的设计和实现中保持风格一致,这一点对于团队合作尤其重要。例如:classPerson:num=0 #成员变量(属性)defSayHello(self): #成员函数print("Hello!");classCar:definfor(self): print("Thisisacar")6.2.1类定义语法定义了类之后,可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法,例如下面的代码:>>>car=Car()>>>r()Thisisacar在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例,下面的代码演示了isinstance()的用法。>>>isinstance(car,Car)True>>>isinstance(car,str)Falseself参数类的所有实例方法都必须至少有一个名为“self”的参数,并且必须是方法的第一个形参(如果有多个形参的话),“self”参数代表将来要创建的对象本身。在类的实例方法中访问实例属性时需要以“self”为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数,如果在外部通过类名调用对象方法则需要显式为self参数传值。【例6-2】定义一个复数类Complex,构造函数完成对象变量初始化工作。classComplex:def__init__(self,realpart,imagpart):self.r=realpartself.i=imagpartx=Complex(3.0,-4.5)print(x.r,x.i)6.2.2构造函数__init__Python中类的析构函数是__del__,用来释放对象占用的资源,在Python收回对象空间之前自动执行。如果用户未涉及析构函数,Python将提供一个默认的析构函数进行必要的清理工作。6.2.3析构函数classComplex:def__init__(self,realpart,imagpart):self.r=realpartself.i=imagpartdef__del__(self):print("Complex不存在了")x=Complex(3.0,-4.5)print(x.r,x.i)print(x)delx #删除x对象变量实例属性属于实例(对象)只能通过对象名访问;类属性属于类可通过类名访问,也可以通过对象名访问,为类的所有实例共享。6.2.4实例属性和类属性【例6-3】定义含有实例属性(姓名name,年龄age)和类属性(人数num)的Person人员类classPerson: num=1 #类属性 def__init__(self,str,n): #构造函数 =str #实例属性 self.age=n defSayHello(self): #成员函数 print("Hello!") defPrintName(self): #成员函数 print("姓名:",,"年龄:",self.age) defPrintNum(self): #成员函数 print(Person.num) #由于是类属性,所以不写self.num#主程序P1=Person("夏敏捷",42)P2=Person("王琳",36)P1.PrintName()P2.PrintName()Python并没有对私有成员提供严格的访问保护机制。在定义类的属性时,如果属性名以两个下划线“__”开头则表示是私有属性,否则是公有属性。私有属性在类的外部不能直接访问,需通过调用对象的公有成员方法来访问,或者通过Python支持的特殊方式来访问。Python提供了访问私有属性的特殊方式,可用于程序的测试和调试,对于成员方法也有同样性质。6.2.5私有成员与公有成员classCar:price=100000 #定义类属性def__init__(self,c,w):self.color=c #定义公有属性colorself.__weight=w #定义私有属性__weight#主程序car1=Car("Red",10.5)car2=Car("Blue",11.8)print(car1.color)print(car1._Car__weight)print(car1.__weight) #AttributeError在类中定义的方法可以粗略分为3大类:公有方法、私有方法、静态方法。公有方法、私有方法都属于对象,私有方法的名字以两个下划线“__”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象的方法中通过“self”调用或在外部通过Python支持的特殊方式来调用。静态方法可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员

加粗6.2.6方法classPerson:num=0 类属性

def__init__(self,str,n,w): #构造函数

=str #对象实例属性(成员)

self.age=nself.__weight=w #定义私有属性__weightPerson.num+=1def__outputWeight(self): #定义私有方法outputWeightprint("体重:",self.__weight) #访问私有属性__weightdefPrintName(self): #定义公有方法(成员函数)

print("姓名:",,"年龄:",self.age,end="")self.__outputWeight() #调用私有方法outputWeightdefPrintNum(self): #定义公有方法(成员函数)

print(Person.num) #由于是类属性,所以不写self.num@staticmethoddefgetNum(): #定义静态方法getNumreturnPerson.num#主程序P1=Person("夏敏捷",42,120)P2=Person("张海",39,80)#P1.outputWeight() #错误'Person'objecthasnoattribute'outputWeight'P1.PrintName()P2.PrintName()Person.PrintName(P2)print("人数:",Person.getNum())print("人数:",P1.getNum())6.3类的继承和多态

继承用于指定一个类将从其父类获取其大部分或全部功能。它是面向对象编程的一个特征。这是一个非常强大的功能,方便用户对现有类进行几个或多个修改来创建一个新的类。新类称为子类或派生类,从其继承属性的主类称为基类或父类。

子类或派生类继承父类的功能,向其添加新功能。它有助于代码的可重用性。6.3类的继承和多态6.3.1类的继承class派生类名(基类名):

派生类成员注意:基类名写在括号里。classParent:#定义父类parentAttr=100def__init__(self):print("调用父类构造函数")defparentMethod(self):print("调用父类方法")defsetAttr(self,attr):Parent.parentAttr=attrdefgetAttr(self):print("父类属性:",Parent.parentAttr)

classChild(Parent):#定义子类def__init__(self):print("调用子类构造函数")defchildMethod(self):print("调用子类方法childmethod")在Python中继承的一些特点:(1)在继承中基类的构造函数(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。(2)如果需要在派生类中调用基类的方法时,通过“基类名.方法名(self)”的方式来实现,需要加上基类的类名前缀。区别于在类中调用普通函数时并不需要带上self参数。也可以使用内置函数super()实现这一目的。(3)Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。从盒子Box派生出彩色盒子ColorBox。classBox():def__init__(self,w,h):self.width=wself.height=hdefprintinfo(self):print(self.width,self.height)#子类classColorBox(Box):def__init__(self,w,h,c):#self.width=w#self.height=tself.color=cBox.__init__(self,w,h)#必须写

defprintinfo(self):

Box.printinfo(self)print(self.color)#主程序c1=ColorBox(1,2,"red")c1.printinfo()6.3类的继承和多态我们来看一个简单的python继承示例,Animal是父类或基类Dog是Animal的子类。在这里,在Animal类中定义了eat()方法,Dog类中定义了bark()方法。在这个例子中,我们创建Dog类的实例,并且仅通过子类的实例调用eat()和bark()方法。由于父属性和行为自动继承到子对象,所以通过子实例也可以调用父类和子类的方法。classAnimal:defeat(self):print'Eating...'classDog(Animal):defbark(self):print'Barking...'d=Dog()d.eat()d.bark()执行上面代码,得到以下结果-Eating...Barking...6.3.2类的多继承Python的类可以继承多个基类。继承的基类列表跟在类名之后。类的多继承语法:classSubClassName(ParentClass1[,ParentClass2,...]):

派生类成员classA:#定义类A.....

classB:#定义类B.....

classC(A,B):#派生类C继承类A和B.....6.3.3方法重写6.3.3方法重写重写必须出现在继承中。它是指当派生类继承了基类的方法之后,如果基类方法的功能不能满足需求,需要对基类中的某些方法进行修改,可以在派生类重写基类的方法,这就是重写。6.3.3方法重写classAnimal: #定义父类

defrun

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论