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

下载本文档

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

文档简介

第七章面向对象程序设计1常州工业职业技术学院19五月2026Python程序设计丁辉袁凯烽商俊燕韩少勇范晓玲郝亚平王霞俊吴春晖目录

Contents01面向对象程序设计基础02继承03多态04面向对象程序设计精选案例0507小结2面向对象程序设计基础014

面向对象程序设计(ObjectOrientedProgramming,简称OOP)是一种把面向对象的思想应用于程序设计的软件开发方法。面向对象程序设计可以使得软件设计更加灵活,能够很好地支持代码复用和设计复用,使代码具有更好的可读性和可扩展性,是软件设计的重器。

面向对象是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界;面向对象程序设计的一个关键性概念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。通过对相同类型的对象进行分类、抽象后,得出共同的特征而形成了类。面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系。面向对象程序设计中的概念主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性。通过这些概念使面向对象的思想得到了具体的体现。Python完全采用了面向对象程序设计的思想,是真正面向对象的高级动态编程语言。Python中的一切都可以看着对象,如数值、字符串、列表、元组、字典、集合等等都是对象。Python语言完全支持面向对象的封装、继承、多态以及对基类方法的覆盖或重写等基本功能。在Python中,所有数据类型都被视为对象,如字符串、列表、字典、元组等内置数据类型都具有和对象完全相似的语法和用法。面向对象程序设计概述5类的定义:类是对一类具有共同特征事物的抽象。Python中,类定义的一般格式如下:

class类名:

类体>>>classCar:#定义汽车类,类名称:Car name='passat'#定义类属性:name,值为'passat' price='190000'#定义类属性:price,值为'190000' defdrive():#定义类方法,方法名称:driveprint('Icanrun.’)

当定义了一个类以后就产生了一个类对象。类对象可以进行两种操作:一种是引用,即通过类本身这个对象来引用(访问)类中的属性或方法,如C,Car.price,Car.Drive();另外一种是实例化,即通过类来产生一个具体的实例对象,然后通过实例对象来访问类中定义的属性或方法。1.类和对象6实例对象的创建和使用

实例对象创建和使用的一般格式是:

实例对象名=类名([参数列表])

#实例化对象实例对象创建后,就可以使用“.”运算符来访问这个实例对象原自类的属性和方法。

实例对象名.属性名#访问实例对象的属性

实例对象名.方法名()

#访问实例对象的方法>>>car1=Car()#利用定义的汽车类Car创建一个汽车实例对象car1>>>#查看的值‘passat'>>>car1.price#查看car1.price的值‘190000'>>>Car.name#访问Car类的属性‘passat'>>>=‘ford’#给实例对象car1的name属性赋值'ford'>>>car1.price=‘180000’#给实例对象car1的price属性赋值'180000'>>>#查看的值'ford'>>>car1.price#查看car1.price的值'180000'1.类和对象7类属性:类属性就是类(即类对象)中所定义的属性,有公有的和私有的类属性两种。>>>classCar:#定义汽车类,类名称:Carname='passat'#定义公有的类属性:name,值='passat’__color='red'#定义私有的类属性:__color,值='red’#属性名前加两个短画线”__”即为私有属性。>>>car1=Car()#创建一个汽车对象car1>>>#通过类的实例car1访问公有的类属性:name'passat'>>>C#通过类对象Car访问公有的类属性:name'passat'

>>>car1.__color#通过实例对象car1访问私有的类属性:__color,错误Traceback(mostrecentcalllast):#错误信息提示File"<pyshell#13>",line1,in<module>car1.__colorAttributeError:'Car'objecthasnoattribute'__color'>>>Car.__color#通过类对象Car访问私有的类属性:__color,错误Traceback(mostrecentcalllast):#错误信息提示File"<pyshell#14>",line1,in<module>Car.__colorAttributeError:typeobject'Car'hasnoattribute'__color'2.类属性和实例属性8#类属性还可以在类定义结束之后通过“类名.新属性”增加,如下给汽车类Car增加id属性:>>>Car.id=’201805150010001’>>>Car.id#在类定义结束之后增加的id属性为汽车类Car的公有属性‘201805150010001’

>>>car1.id#汽车类Car的任何一个实例化对象都可以访问增加的id属性'201805150010001’

#如果给已存在的类属性赋新值,则类的默认值和新创建实例的值都变为新的值>>>C#查看汽车类Car中定义的公有属性name'passat'>>>C='polo'#在类外部给汽车类Car公有属性name赋新的值'polo'>>>C#查看类对象Car的name值'polo'#汽车类对象Car公有属性name值变为'polo'>>>car1=Car()#创建汽车类Car实例化对象car1>>>#查看实例化对象car1的name值'polo'#汽车类Car实例化对象car1的name值也变为'polo’#如果在类定义的外部对汽车类Car进行实例化,产生实例对象car1,然后对car1增加产地属性adress,#则该属性为实例对象car1所特有,汽车类Car和Car其它实例对象如car2并没有该属性>>>car1.address='beijing'>>>car1.adress'beijing'>>>car2=Car()>>>car2.adressTraceback(mostrecentcalllast):#错误信息提示File"<pyshell#11>",line1,in<module>car2.adressAttributeError:'Car'objecthasnoattribute'adress'2.类属性和实例属性9实例属性:一般是在__init___构造函数中定义的,定义时以self作为构造函数的第一个形式参数,其中函数体中的属性前缀是self,即self.实例属性。实例属性只能通过实例对象名访问,不能通过类名访问实例属性。>>>classCar:

price='180000'#定义类属性 def__init__(self,c): #定义构造函数

self.color=c#定义实例属性>>>car1=Car('red')#实例化对象>>>car2=Car('red')#实例化对象>>>car1.color#查看实例car1属性的值'red'>>>car2.color #查看实例car2属性的值'red'>>>Car.price #查看类Car属性的值'180000'

2.类属性和实例属性10>>>Car.color#不能通过类对象来查看实例对象的属性color的值Traceback(mostrecentcalllast):#错误信息提示File"<pyshell#38>",line1,in<module>Car.colorAttributeError:typeobject'Car'hasnoattribute'color'>>>Car.price='200000' #修改类属性值>>>car1.color='Yellow' #修改实例car1属性>>>Car.price #查看类Car属性的值'200000'>>>car1.color #查看car1属性的值'Yellow'>>>car2.color #查看car2属性的值'red'2.类属性和实例属性11类方法:类中定义的方法可以粗略分为:特殊方法、公有方法、私有方法、静态方法和类方法等。>>>classCar: __distance=0 def__init__(self,name):#构造函数 self.__name=name Car.__distance+=1 defshow(self):#公有的实例方法 print("self.__name",self.__name) print("Car.distance",Car.__distance) @classmethod#修饰器,声明类方法 defclassShowdistance(cls):#类方法 print(cls.__distance) @staticmethod#修饰器,声明静态类方法 defstaticShowdistance():#静态方法 print(Car.__distance)>>>car1=Car('passat')>>>car1.classShowdistance()#通过实例对象来调用类方法1>>>car1.staticShowdistance()#通过实例对象来调用静态方法13.类方法12>>>car1.show()#通过实例对象来调用公有实例方法self.__name:passatCar.__distance:1>>>car2=Car('benz')>>>Car.classShowdistance()#通过类名调用类方法2>>>Car.staticShowdistance()#通过类名调用静态方法2>>>Car.show()#通过类名直接调用实例方法失败,错误信息如下:Traceback(mostrecentcalllast):File"<pyshell#72>",line1,in<module>Car.show()TypeError:show()missing1requiredpositionalargument:'self'>>>Car.show(car1)#通过类名调用实例方法时为self参数显式传递对象名,访问实例属性self.__name:passatCar.__distance:2>>>Car.show(car2)#通过类名调用实例方法时为self参数显式传递对象名,访问实例属性self.__name:benzCar.__distance:23.类方法13Python中类的构造函数(即构造方法)是__init__(self,….),一般用来为对象属性设置初值或进行其它必要的初始化工作,在创建实例对象时被自动调用和执行。如果用户没有在类中显式设计构造函数,Python将提供一个默认的构造函数用来进行必要的初始化工作。除构造函数之外,Python还支持析构函数、运算符重载等大量的特殊方法。

类方法是类所拥有的方法,需要用修饰器@classmethod来声明,第一个参数必须是类对象,一般用cls作为类方法的第一个参数名称,但也可以使用其它的名字作为参数,并且在调用类方法时不需要为该参数传递值;静态方法需要用修饰器@staticmethod来声明是静态方法,静态方法可以没有参数,但如果要在静态方法中引用类属性,必须通过类来引用。类方法和静态方法都可以通过类名和对象名调用,但不能直接访问属于实例对象的属性,只能访问属于类的属性。类对象和实例对象都可以调用类方法和静态方法。3.类方法继承0215

继承是用来实现代码复用和设计复用的机制,是面向对象程序设计的重要特性之一。设计一个新类时,如果可以继承一个已有的设计良好的类,然后进行二次开发,将大幅度减少开发工作的代码量。在继承关系中,已有的、设计好的类称为父类、超类或基类,新设计的类称为子类或派生类。Python中类继承定义的一般形式如下:class子类名(父类名):

类体>>>classPerson(object):#定义父类,其实父类本身也是继承了Python中的object类

def__init__(self,name,age,sex):#定义构造方法=nameself.age=ageself.sex=sexprint('initperson:',)defshowinfor(self):#定义实例方法print('name:{};age:{};sex:{}'.format(,self.age,self.sex))继承16>>>classTeacher(Person):#定义Teacher子类,继承Person类

def__init__(self,name,age,sex,department):Person.__init__(self,name,age,sex)#必须在子类中显式调用父类的构造方法print('initTeachername:',self.name)self.department=departmentPerson.showinfor(self)#显式调用父类的实例方法,必须以self传递参数

print('department:',self.department)

继承17继承>>>classStudent(Person):#定义Student子类,继承Person类

def__init__(self,name,age,sex,marks): Person.__init__(self,name,age,sex)#必须在子类中显式调用父类的构造方法

self.marks=marks print('initStudentname:',) Person.showinfor(self)#显式调用父类的实例方法,必须以self传递参数

print('marks:',self.marks)>>>t=Teacher(‘Jake’,36,‘男','compute’)initperson:JakeinitTeachername:Jakename:Jake;age:36;sex:男department:compute>>>s=Student('Rose',23,‘女',90)initperson:RoseinitStudentname:Rosename:Rose;age:16;sex:女

marks:90私有的属性和方法不能继承,即以两个“__”开头,不以“__”结尾的属性和方法。18继承Python支持多重继承,所谓多重继承是指子类有两个或两个以上父类。如果基类有相同的方法名,而在子类中使用时没有指定基类名,则Python解释器将从左到右按顺序搜索,执行第一个搜索到的父类中该同名方法。>>>classA(): defshow(self):print("IcomefromclassA“)>>>classB(A):#类B继承了类A defshow(self): print("IcomefromclassB")>>>classC(A):#类C继承了类A defshow(self): print("IcomefromclassC")>>>classD(B,C):#类D是多重继承,分别继承类B和类Cpass#占位作用,不执行>>>d=D()>>>d.show()#执行类B的方法IcomefromclassB多态0320

多态(polymorphism),按字面的意思就是“多种状态”。通俗点说就是不同的对象去干同一件事情时会产生不同的状态。以买火车票为例,普通人买票就要付全款,学生买票就可以出半价,军人虽然不能优惠但是可以优先买票。在面向对象程序中就是不同继承关系的对象去调用同一个函数,会产生不同的状态。多态的概念依赖于继承。如下,Animal动物类,又分为Dog狗类、Cat猫类、Tiger虎类。#定义基类(父类),其实基类本身也是继承了Python中的object类>>>classAnimal(object):#定义父类def__init__(self,name): =namedefsaymyself(self):#定义基类的方法 print('In_Animal_class:Iama{}.'.format())>>>classCat(Animal):#定义子类defsaymyself(self):#同名的方法实现不同的功能print('In_Cat_class:Iama{}.'.format())>>>classDog(Animal):#定义子类defsaymyself(self):#同名的方法实现不同的功能print('In_Dog_class:Iama{}.'.format())>>>classTiger(Animal):#定义子类defsaymyself(self):#同名的方法实现不同的功能print('In_Tiger_class:Iama{}.'.format())多态21>>>deftestfunc(obj):#定义一个测试函数print('{}say:'.format())#输出实例的name属性值 obj.saymyself()#调用实例的方法>>>animal1=Animal('animal')#创建不同的对象>>>cat1=Cat('cat')>>>dog1=Dog('dog')>>>tiger1=Tiger('tiger')>>>lst=[animal1,cat1,dog1,tiger1]>>>foriinlst:print()testfunc(i)animal#输出基类实例对象的属性animalsay:In_Animal_class:Iamaanimal.#通过基类实例对象调用基类实例对象的方法cat

#输出子类实例对象的属性catsay:In_Cat_class:Iamacat.#通过子类实例对象调用子类实例对象同名的方法,表现出多态多态22dog

#输出子类实例对象的属性dogsay:In_Cat_class:Iamadog.tiger

#输出子类实例对象的属性tigersay:In_Tiger_class:Iamatiger.>>>isinstance(animal1,Animal)True>>>isinstance(cat1,Animal)True>>>isinstance(cat1,Cat)True>>>isinstance(dog1,Animal)True>>>isinstance(dog1,Dog)True>>>isinstance(dog1,Cat)False多态23

多态体现在多个方面:①方法的多态性,上述所定义的Car、Dog、Tiger类都继承了Animal类,但是每个子类都对父类的saymyself()进行了重新定义,从而体现了方法的多态性。②变量的多态性,通过isinstance()函数的测试可以看到,dog1既是Animal的实例,又是Dog的实例,以此可以看到变量的多态性。③参数的多态性,“deftestfunc(obj):”所定义函数的参数obj,可以是任何的对象,因此在“>>>foriinlst: print()testfunc(i)”

语句中调用testfunc()时,分别传递了animal1、cat1、dog1和tiger1实例对象。从而体现了参数的多态性,其实我们在第5章函数部分,就已经在用了参数的多态性,当时我们定义了add(x,y)函数,可以对整数、实数、复数以及列表、元组和字符串求和,所求的和,是根据输入参数来确定的。多态面向对象程序设计精选案例0425【例7-1】请分别用面向过程程序设计和面向对象程序设计方法实现学生姓名和成绩信息的输入和输出。

#定义一个函数输入学生的信息definput_studentinfor():#定义一个字典,存放学生信息stud={"name":[],"score":[]}num=int(input("请输入学生数:"))foriinrange(num):stud['name'].append(input('请输入姓名:'))stud['score'].append(float(input('请输入成绩:')))returnstud

面向过程的方法精选案例#定义一个函数输出学生的信息defoutput_studentinfor(**stud):#输出学生信息的表头forkinstud.keys():print(k,end='')print()#获取学生数num=len(stud['name'])#输出每个学生的具体信息foriinrange(num):print(stud['name'][i],"",stud['score'][i])

if__name__=='__main__':stud=input_studentinfor()output_studentinfor(**stud)分析:(1)信息的存储采用字典方式;(2)定义一个输入函数,一个输出函数。26#定义一个Student类classStudent(object):def__init__(self,name,score):=nameself.score=scoredefoutput_studentinfor(self):print(,"",self.score)#输入信息definput_infor():stu=[]num=int(input("请输入学生数:"))foriinrange(num):name=input("请输入姓名:")score=float(input("请输入分数:"))#创建每个学生对象student=Student(name,score)#将每个学生追加到列表里stu.append(student)returnstu面向对象的方法

采用面向对象程序设计方法,关键就是如何合理地定义和组织类。首先抽象出学生Student类,然后定义学生类的name和score属性,以及将学生信息输出的方法,再根据类来创建每个学生实例,将学生实例存入列表中。#输出信息defoutput_infor(*stu):num=len(stu)print(num)print("name","","score")foriinrange(num):stu[i].output_studentinfor()

if__name__=="__main__":stu=input_infor()output_infor(*stu)精选案例27

【例7-2】请用面向对象的程序设计方法编程计算圆和矩形的面积。要求定义一个形状基类,圆和矩形是子类。importmath#定义一个基类classShape:defarea(self):return0.0#定义子类圆classCircle(Shape):def__init__(self,r=0.0):self.r=rdefarea(self):returnmath.pi*self.r*self.r#定义子类矩形classRectangle(Shape):def__init__(self,a,b):self.a,self.b=a,bdefarea(self):returnself.a*self.b

形状基类的定义,由于不同形状所具有的属性不相同,因此形状基类只定义了一个area()方法。各子类中分别定义各自形状的特征属性,并且在各子类中分别重载area()方法。精选案例

if__name__=="__main__":#计算半径为5的圆的面积c=Circle(5)print("半径=",c.r,"面积=",c.area())#计算矩形的面积r=Rectangle(12.5,5.6)print("矩形的边长分别是:",r.a,",",r.b,"面积是:",r.area())

通过对学生成绩管理系统的设计与实现,进一步理解面向对象程序设计方法,会用面向对象的方法完成小型系统的开发。附加项目--学生成绩管理系统训练目标训练内容

简单学生成绩管理系统要求具有课程与成绩录入、总分计算、按总分排序、最高分和最低分计算等功能。信息输入和输出要简洁明了,增加必要的提示等。姓名C#JAVA英语数学总分李明65723686

王兵81706571

刘萍73648865

课程名称任课教师C#王长荣JAVA李小小英语刘卫兵数学张常来学生成绩登记表课程与教师表

本学生成绩管理系统就是帮班主任完成“学生成绩登记表”和“课程与教师表”基本信息的录入,并求总分、排名和最高分及最低分。训练步骤①设计分析本系统功能相对简单,关键是如何合理地定义相关的类来描述对象。这里设计分数(Score)、课程(Subject)以及学生(Student)三个类。分数(Score)类具有分数属性和输入、输出功能;课程(Subject)类具有课程名称和任课教师两个属性,以及输入、输出功能;学生(Student)类具有姓名、成绩、课程等属性和输入成绩、输出成绩、求总分等功能。②程序编写#eg7_p_1.py#简单学生成绩管理系统#定义分数类classScore():def__init__(self):self.s=0definput(self):self.s=float(input("请输入分数(0~100):"))defoutput(self):print(self.s,end='')附加项目--学生成绩管理系统#定义课程类,包含课程名称和教师classSubject():def__init__(self):self.subject=''self.teacher=''definput(self):self.subject=str(input("请输入课程名称:"))self.teacher=str(input("请输入任课教师:"))defoutput(self):print(self.subject,self.teacher)训练步骤#定义学生类classStudent():def__init__(self,s):=''self.sum=0self.grade={}self.subject=s#输入每门课的成绩,用字典进行存储

definput(self):=str(input("请输入学生姓名:"))foriinself.subject:#成绩输入print(i.subject,'课程',end=":")s=Score()s.input()self.grade[i]=s#求总分defcount(self):foriinself.subject:self.sum+=self.grade[i].s#输出每门课的成绩及总分defoutput(self):print(,end='')foriinself.subject:self.grade[i].output()print(self.sum)附加项目--学生成绩管理系统#课程输入函数,返回课程列表

defkc():print("***课程信息输入***")sub=[]whileTrue:subject=Subject()subject.input()ifsubject.subject=='**':#以输入"**"结束breakelse:sub.append(subject)returnsub

#学生成绩输入函数,

温馨提示

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

评论

0/150

提交评论