资源简介 单元6 类定义与使用课程名称 Python程序设计任务驱动式教程 章名 类定义与使用教学内容 类定义与使用 课时 4项目性质 □演示性 □验证性 □设计性 √综合性授课班级 授课日期 授课地点教学目标 了解Python身份运算符等基础知识 掌握创建类及其对象 了解类属性与实例属性 掌握实例方法、类方法与静态方法 掌握类的构造方法与析构方法 掌握类的继承与方法重写 掌握命名空间与类成员的访问限制教学内容 创建类及其对象 类属性与实例属性 实例方法、类方法与静态方法 类的构造方法与析构方法 类的继承与方法重写 命名空间与类成员的访问限制教学重点 实例方法、类方法与静态方法教学难点 实例方法、类方法与静态方法教学准备 装有Python的计算机 教学课件PPT 教材:《Python程序设计任务驱动式教程(微课版)》作业设计25教学过程教学环节 教学内容与过程 (教学内容、教学方法、组织形式、教学手段)课前组织 做好上课前的各项准备工作(打开计算机、打开课件、打开软件、打开授课计划、教案等),吸引学生注意力。课程说明 【课前说明】 从Python身份运算符等知识点进行初步的了解。 【目的】 使学生从了解本节课的学习目标、学习重点、考评方式等方面明确课程学习的要求和目标。课程内容描述 6.1 创建类及其对象 Python中,类表示具有相同属性和方法的对象的集合。在使用类时,需要先定义类,再创建类的实例,通过类的实例就可以访问类中的属性和方法了。 6.1.1 定义类 Python中,类的定义使用class关键字来实现,定义类的基本语法格式如下。 class ClassName: #类体 其中,ClassName用于指定类名称,一般使用大写字母开头,如果类名称中包括多个单词,后面的单词的首字母也要大写,即采用“大驼峰法命名法”,这是类名称的命名惯例,一般应遵守;statement表示类体,类体主要包括类属性定义和方法定义。如果在定义类时,暂时还不需要编写代码,可以在类体中直接使用pass语句代替实际的程序代码。 6.1.2 创建类的实例 类定义完成后,并不会创建实例对象,在类定义完成后,还需要创建类的实例,即实例化该类的对象。类的实例化也称为创建对象,创建类的实例的基本语法格式如下。 ClassName(parameterlist) 其中,ClassName是必选名称,用于指定具体的类名称;parameterlist是可选参数,当创建一个类时,没有创建__init__()方法,或者当__init__()方法只有一个self参数时,parameterlist允许省略。 【实例6-2】演示Python类的定义与类的实例的创建 实例6-2的代码如下所示。 from datetime import datetime, date class Person: name = "李明" birthday="2000-11-11" def calculateAge(self): today = date.today() birthDate = datetime.strptime(self.birthday, "%Y-%m-%d") age=today.year -birthDate.year - \ ((today.month, today.day) < (birthDate.month, birthDate.day)) return age man = Person() #实例化类 print(man) #访问类的属性和方法 print("Person类的属性name值为:", man.name) print("Person类的方法calculateAge()返回值为:", man.calculateAge()) 实例6-2的运行结果如下。 <__main__.Person object at 0x00000291E6BA0160> Person类的属性name值为: 李明 Person类的方法calculateAge()返回值为: 19 实例6-2中首先创建了一个类Person,类Person定义完成后就产生了一个类对象,可以通过类对象来访问类中的属性和方法。 类定义好后就可以进行实例化操作,通过代码“man = Person()”产生一个Person的实例对象,并将该对象赋给变量man,man即实例对象。实例对象是根据类的模板生成的一个内存实体,有确定的数据与内存地址。 6.2 类属性与实例属性 类的成员包括属性和方法,在类中创建了类的成员后,可以通过类的实例进行访问。 在类中定义的变量称为类的属性,根据定义位置不同,可以分为类属性和实例属性。类实例化后,可以使用其属性,实际上,创建一个类之后就可以通过类名称访问其属性。类属性是指在类中方法外定义的属性,包括公有属性、保护属性和私有属性。类属性可以在类的所有实例之间共享,也就是在所有实例化的对象中公用。实例属性在方法内定义,通常在类的__init__()方法中定义,实例属性只属于类的实例,只能通过实例名称访问。 【实例6-3】演示Python类的定义与类属性的定义 实例6-3的代码如下所示。 class Suit: style = "男式西装" #款式 model="170" #型号 clothingLength=74.5 #衣长 bust = 100 #胸围 waistline=89 #腰围 sleeveLength=61.8 #袖长 shoulderWidth=44.8 #肩宽 print("这是", style, "的规格") def printInfo(self): print("我的胸围是:",Suit.bust,"厘米") print("适合我的",self.style,"型号是:",Suit.model) print("Suit类的属性bust值为:", Suit.bust) suit1 = Suit() #实例化类 print("suit1实例的属性suit值为:", suit1.model) suit1.printInfo() 实例6-3的运行结果如下。 这是 男式西装 的规格 Suit类的属性bust值为: 100 suit1实例的属性suit值为: 170 我的胸围是: 100 厘米 适合我的 男式西装 型号是: 170 6.3 实例方法、类方法与静态方法 在类中可以根据需要定义一些方法,定义方法使用def关键字,类方法与普通函数定义不同,类方法包含了一个参数self,且其必须为第一个参数,这里的self代表的是类的实例。 6.3.1 实例方法 Python中的实例方法是类中的一个行为,是类的一部分。所谓实例方法是指在类中定义的函数,该函数是一种在类的实例上操作的函数。同__init()__方法一样,实例方法的第一个参数必须是self,并且必须包含一个self参数。 创建实例方法的基本语法格式如下。 def functionName( self , parameterlist ) <方法体> 其中,functionName表示方法名称,采用“小驼峰法命名法”,使用小写字母开头。self为必要参数,表示类的实例,其名称self并不是规定的名称,只是Python编程时的惯用名称,该名称也可以自定义,例如使用this,但是最好还是按照Python的约定使用self。parameterlist用于指定除self参数以外的参数,各参数之间使用逗号“,”进行分隔。方法体的程序代码用于实现所需的功能。 实例方法创建完成后,类外部可以通过类的实例名称和点“.”进行访问,其基本语法格式如下。 instanceName.functionName( parameterValue ) 其中,instanceName表示类的实例名称;functionName表示要调用的方法名称;parameter Value表示调用方法时的实际参数,其个数与创建的实例方法中parameterlist的个数相同。 【实例6-5】演示Python类的定义与类方法的定义 实例6-5的代码如下所示。 from datetime import datetime, date class Person: """类的属性""" name = "李明" #公有属性 __birthday="2000-11-11" def __calculateAge(self): #私有方法 today = date.today() birthDate = datetime.strptime(self.__birthday, "%Y-%m-%d") age=today.year -birthDate.year - \ ((today.month, today.day) < (birthDate.month, birthDate.day)) return age def getAge(self): return self.__calculateAge() man = Person() #实例化类 print("Person类的方法getAge()返回值为:", man.getAge()) #出现异常,类实例不能访问私有方法 print("Person类的方法__calculateAge()返回值为:", man.__calculateAge()) 实例6-5的运行结果如下。 Traceback (most recent call last): File "D:/PycharmProject/Practice/Unit06/p6-5.py", line 24, in print("Person类的方法__calculateAge()返回值为:", man.__calculateAge()) AttributeError: 'Person' object has no attribute '__calculateAge' Person类的方法getAge()返回值为:19 从实例6-5可以看出方法__calculateAge()的名称由双下画线开头,声明该方法为类的私有方法,只能在类的内部调用,不能在类的外部调用。在类内部调用实例方法的基本语法格式如下。 self.__methodName() 例如: self.__calculateAge() 在类外部可以调用类的公有方法,调用形式有两种。 形式一: 类实例名称.实例方法名称( [参数值列表] ) 例如: man.getAge() 通过类实例名称man调用getAge()方法时,将实例对象man自身作为第一个参数传递给方法的参数self。 形式二: 类名称.实例方法名称( 类实例名称 [, 参数值列表] ) 例如: Person.getAge(man) 通过类名称Person调用getAge()方法时,也需要将实例对象man自身作为参数传递给方法的参数self。 6.3.2 类方法 在Python类的内部,使用def关键字可以定义属于类的方法,这种方法需要使用@classmethod来修饰,而且第一个参数一般命名为cls(这只是Python的惯用名称,不是强制要求,也可以使用自定义名称,例如my)。类方法一般使用类的名称来调用,调用时会把类名称传递给类的第一个参数cls。 调用类方法的基本语法格式如下。 形式一: 类实例名称.类方法名称( [参数列表] ) 形式二: 类名称.类方法名称( [参数列表] ) 6.3.3 静态方法 在Python类的内部,还可以定义静态方法,这种静态方法需要使用@staticmethod来修饰,静态方法的参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法; 实例对象和类对象都可以调用类的静态方法,要访问类的静态方法,可以采用类名称调用,并且不会向静态方法传递任何参数。 调用类静态方法的基本语法格式如下。 形式一: 类实例名称.类静态方法名称() 形式二: 类名称.类静态方法名称() 静态方法是类中的函数,不需要实例。静态方法逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。 【任务6-1】定义商品类及其成员 【任务描述】 (1)在PyCharm集成开发环境中创建项目Unit06。 (2)在项目Unit06中创建Python程序文件6-1.py。 (3)定义商品类Commodity。 (4)定义类的多个公有属性和私有属性。 (5)定义多个实例方法。 (6)分别通过类名称、实例名称访问类的属性。 (7)分别通过类的实例方法输出类的公有属性和私有属性。 【任务实施】 1.创建PyCharm项目Unit06 成功启动PyCharm后,在指定位置“D:\PycharmProject\”创建PyCharm项目Unit06。 2.创建Python程序文件6-1.py 在PyCharm项目Unit06中新建Python程序文件6-1.py,同时PyCharm主窗口显示程序文件6-1.py的代码编辑窗口,在该程序文件的代码编辑窗口自动添加了模板内容。 3.编写Python程序代码 在新建文件6-1.py的代码编辑窗口已有模板注释内容下面输入程序代码,程序文件6-1.py中定义类Commodity的代码如电子活页6-1所示。 针对创建的类Commodity实施以下各项操作。 (1)直接使用类名称访问类的公有属性。 直接使用类名称访问类的公有属性的代码如下。 print("商品编号:"+Commodity.commodityCode) print("商品名称:"+Commodity.commodityName) print("价 格:"+"{:.2f}".format(Commodity.commodityPrice)) print("生产日期:"+Commodity.produceDate) 其运行结果如图所示。 运行结果(1) (2)使用类的实例名称访问类的公有属性。 使用类的实例名称访问类的公有属性的代码如下。 goods=Commodity() print("商品编号:"+modityCode) print("商品名称:"+modityName) print("价 格:"+"{:.2f}".format(modityPrice)) print("生产日期:"+goods.produceDate) 其运行结果如上图所示。 (3)调用类的实例方法输出类的公有属性。 调用类的实例方法输出类的公有属性的代码如下。 goods.printCommodityPublic() 其运行结果如上图所示。 (4)通过类名称或类实例名称访问类的私有属性。 在类外部通过类名称或类实例名称不能直接访问类的私有属性,以下代码访问类的私有属性会出现异常信息,代码以及对应的异常信息见以下注释。 #AttributeError: type object 'Commodity' has no attribute '__code' #print("商品编号:"+Commodity.__code) #AttributeError: type object 'Commodity' has no attribute '__name' #print("商品名称:"+Commodity.__name) #AttributeError: 'Commodity' object has no attribute '__price' #print("价 格:"+"{:.2f}".format(goods.__price)) #AttributeError: 'Commodity' object has no attribute '__date' #print("生产日期:"+goods.__date) (5)调用类的实例方法输出类的私有属性。 调用类的实例方法输出类的私有属性的代码如下。 goods.printLine() goods.printCommodityPrivate() Commodity.printLine(goods) 其运行结果如下。 --------------------------------------------------------------- 商品编号:65559628242 商品名称:海信(Hisense)100L7 价 格:79999.00 生产日期:2020/1/6 --------------------------------------------------------------- 【任务6-2】修改与访问类属性、建立实例属性 【任务描述】 (1)在项目Unit06中创建Python程序文件6-2.py。 (2)创建类Commodity与定义其属性和方法。 (3)创建类对象goods1和goods2。 (4)通过类名称Commodity调用类的实例方法输出类初始定义的公有属性。 (5)使用类名称Commodity修改类的公有属性,代码如下所示。 Commodity.commodityCode="12563157" Commodity.commodityName="给Python点颜色 青少年学编程" Commodity.commodityPrice=59.80 Commodity.produceDate="2019/9/1" (6)直接使用类名称Commodity输出类修改之后的公有属性。 (7)使用类实例名称goods1输出类修改之后的公有属性。 (8)使用第2个实例名称goods2输出类修改之后的公有属性。 (9)通过类名称Commodity调用类的实例方法输出类修改之后的公有属性。 (10)通过实例名称goods1调用类的实例方法输出类修改之后的公有属性。 (11)第2次修改类的公有属性,代码如下所示。 goods1.commodityCode="4939815" goods1.commodityName="格力KFR-72LW/NhIbB1W" goods1.commodityPrice=9149.00 goods1.produceDate="2019/8/8" (12)直接使用类名称Commodity输出类第2次修改之后的公有属性。 (13)使用第1个实例名称goods1输出类第2次修改之后的公有属性。 (14)使用第2个实例名称goods2输出类第2次修改之后的公有属性。 (15)通过类名称Commodity调用类的实例方法输出类第2次修改之后的公有属性。 (16)分别通过实例名称goods1、goods2调用类的实例方法输出类第2次修改之后的公有属性。 【任务实施】 在PyCharm项目Unit06中新建Python程序文件6-2.py,在程序文件6-2.py的代码编辑窗口创建类Commodity与定义其属性和方法,程序6-2.py中定义类Commodity的代码如电子活页6-2所示。 针对创建的类Commodity实施对类属性、实例属性的修改与访问。 1.创建类对象 创建两个类对象goods1和goods2的代码如下。 goods1=Commodity() goods2=Commodity() 2.通过类名称Commodity调用类的实例方法输出类初始定义的公有属性 对应代码如下。 Commodity.printCommodityPublic(goods1) 其运行结果如图6-3所示。 3.使用类名称Commodity修改类的公有属性 对应代码如下。 Commodity.commodityCode="12563157" Commodity.commodityName="给Python点颜色 青少年学编程" Commodity.commodityPrice=59.80 Commodity.produceDate="2019/9/1" 4.直接使用类名称Commodity输出类修改之后的公有属性 对应代码如下。 print("商品编号:"+Commodity.commodityCode) print("商品名称:"+Commodity.commodityName) print("价 格:"+"{:.2f}".format(Commodity.commodityPrice)) print("生产日期:"+Commodity.produceDate) 其运行结果如图所示。 运行结果(2) 5.使用类实例名称goods1输出类修改之后的公有属性 对应代码如下。 print("商品编号:"+goods1.commodityCode) print("商品名称:"+goods1.commodityName) print("价 格:"+"{:.2f}".format(goods1.commodityPrice)) print("生产日期:"+goods1.produceDate) 其运行结果如上图所示。 6.使用第2个实例名称goods2输出类修改之后的公有属性 对应代码如下。 print("商品编号:"+goods2.commodityCode) print("商品名称:"+goods2.commodityName) print("价 格:"+"{:.2f}".format(goods2.commodityPrice)) print("生产日期:"+goods2.produceDate) 其运行结果如上图所示。 7.通过类名称Commodity调用类的实例方法输出类修改之后的公有属性 对应代码如下。 Commodity.printCommodityPublic(goods1) 其运行结果如上图所示。8.通过实例名称goods1调用类的实例方法输出类修改之后的公有属性 对应代码如下。 goods1.printCommodityPublic() 其运行结果如上图所示。 9.第2次修改类的公有属性 对应代码如下。 goods1.commodityCode="4939815" goods1.commodityName="格力KFR-72LW/NhIbB1W" goods1.commodityPrice=9149.00 goods1.produceDate="2019/8/8" 10.直接使用类名称Commodity输出类第2次修改之后的公有属性 对应代码如下。 print("商品编号:"+Commodity.commodityCode) print("商品名称:"+Commodity.commodityName) print("价 格:"+"{:.2f}".format(Commodity.commodityPrice)) print("生产日期:"+Commodity.produceDate) 其运行结果如上图所示。 11.使用第1个类实例名称goods1输出类第2次修改之后的公有属性 对应代码如下。 print("商品编号:"+goods1.commodityCode) print("商品名称:"+goods1.commodityName) print("价 格:"+"{:.2f}".format(goods1.commodityPrice)) print("生产日期:"+goods1.produceDate) 其运行结果如图所示。 运行结果(3) 12.使用第2个实例名称goods2输出类第2次修改之后的公有属性 对应代码如下。 print("商品编号:"+goods2.commodityCode) print("商品名称:"+goods2.commodityName) print("价 格:"+"{:.2f}".format(goods2.commodityPrice)) print("生产日期:"+goods2.produceDate) 其运行结果如图所示。 运行结果(2) 13.通过类名称Commodity调用类的实例方法输出类第2次修改之后的公有属性 对应代码如下。 Commodity.printCommodityPublic(goods1) 其运行结果如图所示。 运行结果(3) Commodity.printCommodityPublic(goods2) 其运行结果如图所示。 运行结果(2) 14.分别通过实例名称goods1、goods2调用类的实例方法输出类第2次修改之后的公有属性 对应代码如下。 goods1.printCommodityPublic() 其运行结果如图所示。 运行结果(3) goods2.printCommodityPublic() 其运行结果如图所示。 运行结果(2) 【任务6-3】定义与访问类的实例方法 【任务描述】 (1)在项目Unit06中创建Python程序文件6-3.py。 (2)在程序文件6-3.py中创建类对象goods。 (3)在程序文件6-3.py中调用多个类的实例方法,输出所需数据。 【任务实施】 在PyCharm项目Unit06中创建Python程序文件6-3.py。在程序文件6-3.py中编写程序代码,实现所需功能。创建类Commodity及其定义私有属性、实例方法的代码如电子活页6-3所示。 针对创建的类Commodity实施以下各项操作。 1.创建类对象goods 创建一个类对象goods,代码如下。 goods=Commodity() 2.调用多个类的实例方法,输出所需数据 调用多个类的实例方法,输出所需数据的代码如下。 goods.printLine() #使用类的实例方法输出商品数据 goods.printField() print("{:^10s}".format(goods.getCode()),"{:^21s}".format(goods.getName()),end="") print("{:^10.2f}".format(goods.getPrice()),"{:^7s}".format(goods.getDate())) goods.printLine() 程序文件6-3.py的运行结果如图所示。 程序6-3.py的运行结果 【任务6-4】定义与访问类方法、实例方法和静态方法 【任务描述】 (1)在项目Unit06中创建Python程序文件6-4.py。 (2)在程序文件6-4.py中创建类对象goods。 (3)在程序文件6-4.py中使用类的实例名称goods调用类的实例方法和类方法。 (4)在程序文件6-4.py中使用类名称Commodity直接调用类的实例方法和类方法。 (5)在程序文件6-4.py中使用类的静态方法输出商品数据。 【任务实施】 在PyCharm项目Unit06中创建Python程序文件6-4.py。在程序文件6-4.py中编写程序代码,实现所需功能。程序文件6-4.py的代码如电子活页6-4所示。 针对创建的类Commodity实施以下各项操作。 1.创建类对象goods 创建一个类对象goods,代码如下。 goods=Commodity() 2.使用类的实例名称goods调用类的实例方法和类方法 对应代码如下。 goods.printLine() goods.printField() goods.printData() goods.printLine() 其运行结果如图所示。 运行结果 3.使用类名称Commodity直接调用类的实例方法和类方法 对应代码如下。 Commodity.printLine(goods) Commodity.printField(goods) Commodity.printData() Commodity.printLine(goods) 其运行结果如上图所示。 4.使用类的静态方法输出商品数据 对应代码如下。 goods.printLine() goods.printField() Commodity.printDataStatic() goods.printLine() 其运行结果如上图所示。 6.4 类的构造方法与析构方法 面向对象程序设计中,类实例化时往往要对实例做一些初始化工作,例如设置实例属性的初始值等。而这些工作是自动完成的,因此有一个默认的方法被调用,这个默认的方法就是构造方法,与之对应的是析构方法。 6.4.1 类的构造方法 Python中,类有一个名为__init__()的特殊方法称为构造方法,该方法在类实例化时会自动调用,不需要显式调用。 在创建类时,类通常会自动创建一个__init__()方法。每当创建一个类的新实例时,如果用户没有重新定义构造方法,则系统自动执行默认的构造方法__init__(),进行一些初始化操作。如下代码,实例化类Person时,对应的__init__()方法就会被调用。 man = Person () 当然,__init__()方法可以有参数,参数通过__init__()传递到类的实例化操作上。 __init__(self,…)方法必须包含一个self参数,并且必须是第一个参数。self参数是一个指向实例本身的引用,用于访问类中的属性和方法,在方法调用时自动传递参数self。 当__init__()方法只有一个参数时,创建类的实例时就不需要指定实际参数了。系统自动调用__init__()方法,并将类实例本身作为参数向该方法传递。 __init__()方法中,除了self参数外,也可以自定义其他参数,参数之间使用逗号“,”进行分隔。如果该方法包含一个以上参数,创建类的实例时必须指定实际参数,例如man = Person("李明","男", 19)。调用包含一个以上参数的__init__()方法,也是将类实例对象本身作为第一个参数向该方法传递,调用时显式传递的实参值会传递给该方法第一个参数之后的各个参数。 【实例6-6】演示Python类的构造方法定义与私有属性初始化 实例6-6的代码如下所示。 class Person: #定义类属性 __name = "" __sex = "" __age = 0 #定义构造方法 def __init__(self,name1,sex1,age1): self.__name = name1 self.__sex = sex1 self.__age = age1 def printInfo(self): print("姓名:",self.__name) print("性别:",self.__sex) print("年龄:",self.__age) man = Person("李明","男",19) man.printInfo() 实例6-6的运行结果如下。 姓名:李明 性别:男 年龄:19 构造方法__init__()是建立实例对象时自动调用,可以在这个方法中为实例对象初始化属性值。 在子类中定义__init__()方法时,不会自动调用父类的__init__()方法,如果要在子类中使用父类的__init__()方法,必须要进行初始化,即需要在子类中使用父类名称或者super()函数显式调用父类的__init__()方法。 在子类中显式调用__init__()方法的基本语法格式如下。 形式一: 父类名称.__init__( self [ , 参数列表 ] ) 形式二: super().__init__( self [ , 参数列表 ] ) 6.4.2 类的析构方法 Python中,析构方法的基本语法格式为:__del__(self),在释放对象时系统自动调用该方法,不需要显式调用,可以在该方法中编写代码,进行一些释放资源的操作。 【任务6-5】定义与调用类的构造方法 【任务描述】 (1)在项目Unit06中创建Python程序文件6-5.py。 (2)在程序文件6-5.py中定义与调用类的构造方法。 【任务实施】 在PyCharm项目Unit06中创建Python程序文件6-5.py。在程序文件6-5.py中编写程序代码,实现所需功能。程序文件6-5.py的代码如电子活页6-5所示。 针对创建的类Commodity实施以下各项操作。 1.创建第1个类实例goods1,全部参数初始化 代码如下。 goods1=Commodity("12550531","Python编程锦囊(全彩版)",79.80,"2019/06/01") 2.通过第1个类实例goods1调用类的实例方法输出商品数据 代码如下。 goods1.printLine() goods1.printField() goods1.printData() goods1.printLine() 运行结果如图所示。 程序文件6-5.py运行结果的第1部分 3.创建第2个类实例goods2,部分参数初始化 代码如下。 goods2=Commodity("100009177374","华为 Mate 30 Pro 5G") 4.通过第2个类实例goods2调用类的实例方法输出商品数据 代码如下。 goods2.printLine() goods2.printField() goods2.printData() goods2.printLine() 运行结果如图所示。 程序文件6-5.py运行结果的第2部分 5.创建第3个类实例goods3,所有参数都未初始化 代码如下。 goods3=Commodity() 6.对第3个类实例goods3的属性赋值 代码如下。 modityCode="4939815" modityName="格力 KFR-72LW/NhIbB1W " modityPrice=9149.00 goods3.produceDate="2019/08/08" 7.输出3个类实例goods1、goods2、goods3的商品名称 代码如下。 print("商品名称1:"+goods1.commodityName) print("商品名称2:"+goods2.commodityName) print("商品名称3:"+modityName) 运行结果如下。 商品名称1:Python编程锦囊(全彩版) 商品名称2:华为 Mate 30 Pro 5G 商品名称3:格力 KFR-72LW/NhIbB1W 8.通过第3个类实例goods3调用类的实例方法输出商品数据 代码如下。 goods3.printLine() goods3.printField() goods3.printData() goods3.printLine() 运行结果如图所示。 程序文件6-5.py运行结果的第3部分 6.5 类的继承与方法重写 继承是面向对象程序设计最重要的特性之一,程序设计中实现继承,表示这个类拥有它继承的父类的所有公有成员或者受保护成员。在面向对象程序设计中,被继承的类称为父类,新的类称为子类或派生类。 通过继承不仅可以实现代码的重用,还可以理顺类与类之间的关系。继承是实现代码重复利用的重要手段,子类通过继承复用了父类的属性和方法的同时还可以添加子类特有的属性和方法。 6.5.1 类的继承 Python中,可以在类定义语句中类名称右侧添加圆括号“()”,将要继承的父类名称标注,从而实现类的继承。 1.单一继承 Python支持类的继承,单一继承的类定义基本语法格式如下所示。 class DerivedClassName( ParentClassName1 ): <类体> 其中,DerivedClassName用于指定子类名称,ParentClassName1用于指定要继承的父类名称,可以有多个,对于单一继承只有一个。如果不指定父类名称,则继承Python的根类object。类体为实现所需功能的程序代码,包括属性、方法的定义。如果定义类时,暂时没有编写程序代码,可以直接使用pass语句代替。 父类必须与子类定义在一个作用域内。 【实例6-7】演示Python类和单一继承子类的定义 实例6-7的代码如下所示。 class Person: name = "李明" sex="男" class Student(Person): grade = 95 man = Person() #实例化父类 print("父类Person的属性name值为:", man.name) print("父类Person的属性sex值为:", man.sex) student = Student() #实例化子类 print("子类Student的属性name值为:", student.name) print("子类Student的属性sex值为:", student.sex) print("子类Student的属性grade值为:", student.grade) 实例6-7的运行结果如下。 父类Person的属性name值为:李明 父类Person的属性sex值为:男 子类Student的属性name值为:李明 子类Student的属性sex值为:男 子类Student的属性grade值为:95 实例6-7中首先定义一个Person类,该类有2个属性:name、sex;然后定义一个Student子类,Student子类从Person类继承属性和方法,同时可以有自己的属性和方法,这里增加了grade属性,这样Student子类就有3个属性:name、sex、grade。 Person类称为Student类的父类,Student类称为Person类的子类或派生类。即Person类派生出Student类,Student类继承自Person类。 2.多重继承 Python也有限地支持多重继承。多重继承的类定义基本语法格式如下。 class DerivedClassName( ParentClassName1, ParentClassName2,… ): 其中,DerivedClassName用于指定子类名称,ParentClassName1、ParentClassName2……则表示继承的多个父类名称,使用逗号“,”分隔。 需要注意圆括号中父类的顺序。若父类中有相同的方法名,而在子类使用时未指定,Python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。 【实例6-8】演示Python类和多重继承子类的定义 实例6-8的代码如下所示。 class Person: """类的属性""" __name = "李明" #公有属性 __sex = "男" def printTest(self): print("调用父类Person的实例方法printTest()") def printInfo(self): print("姓名:",self.__name) print("性别:", self.__sex) class Student: __grade = 95 def printInfo(self): print("成绩:",self.__grade) class Members(Person,Student): __position = "会长" def printInfo(self): Person.printInfo(self) Student.printInfo(self) print("职务:",self.__position) member =Members() #实例化子类 member.printTest() #调用父类的实例方法 print("调用子类Members的方法printInfo():") member.printInfo() #访问子类Members的方法printInfo() 实例6-8的运行结果如下。 调用父类Person的实例方法printTest() 调用子类Members的方法printInfo(): 姓名:李明 性别:男 成绩:95 职务:会长 6.5.2 方法继承 子类可以继承父类的实例方法,也可以增加自己的新实例方法。子类对象可以直接调用父类的实例方法,调用的基本语法格式如下。 子类名称.父类方法名称( [参数列表] ) 例如: member.printTest() 6.5.3 方法重写 父类的成员都会被子类继承。如果程序中的父类方法的功能不能满足需求,可以在子类重写父类中的同名方法,子类可以覆盖父类中的任何方法,在子类的方法中也可以调用父类中的同名方法。 【实例6-9】演示Python类和子类的定义、方法重写 实例6-9的代码如下所示。 class Person: #定义父类 __name = "李明" def printInfo(self): print("姓名:",self.__name) class Student(Person): #定义子类 grade = 95 def printInfo(self): Person.printInfo(self) print("成绩:",self.grade) student1 = Student() #实例化父类 print("调用子类Student的方法printInfo():") student1.printInfo() #访问子类的重写方法printInfo() print("用子类对象student1调用父类Person的方法printInfo():") super(Student, student1).printInfo() #用子类对象调用父类已被覆盖的方法 实例6-9的运行结果如下。 调用子类Student的方法printInfo(): 姓名:李明 成绩:95 用子类对象student1调用父类Person的方法printInfo(): 姓名:李明 实例6-9中的super()函数用于调用父类的方法。 【任务6-6】定义类Commodity和子类Book及其数据成员 【任务描述】 (1)在项目Unit06中创建Python程序文件6-6.py。 (2)在程序文件6-6.py中定义类Commodity和子类Book及其属性、方法。 (3)应用类的属性与方法实现所需功能。 【任务实施】 在PyCharm项目Unit06中创建Python程序文件6-6.py。在程序文件6-6.py中编写程序代码,实现所需功能。程序文件6-6.py的代码如电子活页6-6所示。 针对创建的类Commodity和子类Book实施以下各项操作。 1.创建第1个类实例goods1,全部参数初始化 创建第1个类实例goods1,全部参数初始化,其代码如下。 goods1=Book("12528944","PPT设计从入门到精通",79.00,"人民邮电出版社",1) 2.通过第1个类实例goods1调用类的实例方法输出图书数据 代码如下。 goods1.printLine() goods1.printField() goods1.printData() goods1.printLine() 运行结果如图所示。 程序文件6-6.py运行结果的第1部分 3.创建第2个类实例goods2,部分参数初始化 代码如下。 goods2=Book("12563157","给Python点颜色 青少年学编程") 4.通过第2个类实例goods2调用类的实例方法给类的部分属性赋值 代码如下。 goods2.setPrice(59.80) goods2.setPublisher("人民邮电出版社") goods2.setEdition(1) 5.通过第2个类实例goods2调用类的实例方法输出图书数据 代码如下。 goods2.printLine() goods2.printField() goods2.printData() goods2.printLine() 运行结果如图所示。 程序文件6-6.py运行结果的第2部分 6.创建第3个类实例goods3,所有参数都未初始化 代码如下。 goods3=Book() 7.通过第3个类实例goods3调用类的实例方法给类的全部属性赋值 代码如下。 goods3.setCode("12550531") goods3.setName("Python编程锦囊(全彩版)") goods3.setPrice(79.80) goods3.setPublisher("吉林大学出版社") goods3.setEdition(1) 8.通过第3个类实例goods3调用类的实例方法输出图书数据 代码如下。 goods3.printLine() goods3.printField() goods3.printData() goods3.printLine() 运行结果如图所示。 程序文件6-6.py运行结果的第3部分 6.6 命名空间与类成员的访问限制 6.6.1 Python 3的命名空间和作用域 在理解Python的命名空间和作用域之前,我们先了解一下计算机中的多个磁盘、多个文件夹与多个文件的存储关系。 计算机中可以有多个硬盘,同一个硬盘中可以有多个逻辑分区(磁盘),同一个磁盘中可以有多个文件夹,同一个文件夹中可以有多个文件。并且要求同一个磁盘中不能出现重名的文件夹,同一文件夹中不能出现重名的文件,但不同磁盘或不同文件夹中的文件可以重名。 下图所示的计算机硬盘中有两个磁盘,分别命名为磁盘E:和磁盘F:,磁盘E:中创建了两个不同名称的文件夹x和y,磁盘F:中也创建了一个文件夹x,由于文件夹x位于不同磁盘,重名是允许的。磁盘E:文件夹x中创建了文件x01.txt和文件02.txt,磁盘E:文件夹y中创建了文件y01.txt和文件02.txt,同名文件02.txt由于存储在不同的文件夹中,是允许的。磁盘F:中创建了文件x01.txt和文件y01.txt,显然,磁盘E:文件夹x与磁盘F:文件夹x中出现了同名文件x01.txt,磁盘E:文件夹y与磁盘F:文件夹x中也出现了同名文件y01.txt,由于存储在不同磁盘的不同文件夹中,也是允许的。 图6-14 计算机中的磁盘、文件夹与文件的存储关系 Python的命名空间提供了在项目中避免名称冲突的一种方法。各个命名空间是独立的、没有任何关系的,所以一个命名空间中不能有重名的对象,但不同的命名空间中是可以有重名的对象而没有任何影响的。 Python的命名空间结构主要由包、模块、类、函数、方法、属性、变量组成,相同的对象名称可以存在于多个命名空间中。一个Python项目中可以定义多个包,并且包名称要求不同,例如package01、package02;一个包中可创建多个模块,同一个包中的多个模块,其名称要求不同,不同包中的模块名称可以重名;一个模块中可以定义多个类、函数、变量,同一个包的同一个模块中定义的类、函数、变量,其名称要求不同,不同的包或同一个包的不同模块中定义的类、函数、变量名称可以重名;一个类中可以定义多个属性、方法,同一个类中的多个属性、方法,其名称要求不同,不同名称的类或不同级别的类(父类与子类)中定义的属性、方法名称可以重名;一个函数中可以定义多个变量,同一个函数中的多个变量,其名称要求不同,不同函数中定义的变量名称可以重名。Python的命名空间结构如图所示。 Python的命名空间结构 1.3种命名空间 Python主要有如下3种命名空间。 (1)内置名称(built-in names)。Python内置的名称,例如函数名abs、chr和异常名称BaseException、Exception等。 (2)全局名称(global names)。模块中定义的名称,记录了模块级变量,包括函数、类、其他导入的模块级的变量和常量。 (3)局部名称(local names)。函数中定义的名称,记录了函数级变量,包括函数的参数和局部定义的变量。类内和类的方法中定义的也属于局部名称。 3种命名空间的作用域示意如图所示。 3种命名空间的作用域示意 2.命名空间的查找顺序 假设我们要使用变量var,则Python的查找顺序为:局部名称→全局名称→内置名称。 如果找不到变量var,Python将放弃查找并引发一个NameError异常,如下所示。 NameError: name 'var' is not defined 3.命名空间的生命周期 命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期结束。因此,我们无法从外部命名空间访问内部命名空间的对象。例如: #var1 是全局名称 var1 = 5 def local_func(): #var2是局部名称 var2 = 6 def inner_func(): # var3是内嵌的局部名称 var3 = 7 4.作用域 作用域就是一个Python程序可以直接访问命名空间的区域。在一个Python程序中,直接访问一个变量会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。 Python中,程序的变量并不是在任何位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。变量的作用域决定了在哪一部分程序可以访问哪些特定的变量。Python的作用域一共有4种,分别如下。 (1)局部作用域(Local,L):最内层,包含局部变量,例如一个函数/方法内部。 (2)闭包函数外的函数中(Enclosing,E):包含了非局部(non-local)、也非全局(non-global)的变量。例如两个嵌套函数,一个函数(或类)A里面又包含了一个函数B,那么对于B中的名称来说A中的作用域就为non-local。 (3)全局作用域(Global,G):当前脚本的最外层,例如当前模块的全局变量。 (4)内置作用域(Built-in,B):包含了内建的变量/关键字等,最后才被搜索。 查找的规则顺序为:L→E→G→B。即在局部作用域找不到,便会去局部作用域外的局部查找(例如闭包函数外的函数),如果没找到就会去全局作用域查找,最后去内置作用域查找。 例如: g_count = 1 #全局作用域 def outer(): o_count = 2 #闭包函数外的函数中 def inner(): i_count = 3 #局部作用域 内置作用域是通过一个名为builtins的标准模块来实现的,但是其自身并没有放入内置作用域内,所以必须导入该模块才能够使用它。在Python 3中,可以使用以下的代码来查看到底预定义了哪些变量。 >>>import builtins >>>dir(builtins) Python中,只有模块、类以及函数才会引入新的作用域,其他代码块(例如try/except、if/elif/else/、for/while等)是不会引入新的作用域的。也就是说这些语句内定义的变量,外部也可以访问,例如: >>>if True: msg = 'I wish you good health.' >>> msg 'I wish you good health.' 实例中msg变量定义在if语句块中,外部是可以访问的。 如果将msg变量定义在函数中,则它就是局部变量,外部不能访问,例如: >>>def printInfo(): msg_inner = 'I wish you good health.' >>>msg_inner 运行时会出现如下异常信息。 Traceback (most recent call last): File "", line 1, in NameError: name 'msg_inner' is not defined 从以上异常信息可以看出,msg_inner未定义,无法使用,因为它是局部变量,只有在函数内才可以使用。 5.全局变量和局部变量 定义在函数内部的变量拥有局部作用域,定义在函数外部的变量拥有全局作用域。 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入作用域中。 【实例6-10】演示Python的全局变量和局部变量的定义与使用 实例6-10的代码如下所示。 amount = 0 #这是一个全局变量 def calculateAmount(quantity, price): "返回2个参数的和." amount = quantity * price #amount在这里是局部变量 print("函数内是局部变量:", amount) return amount #调用calculateAmount()函数 calculateAmount(10, 2.6) print("函数外是全局变量:", amount) 实例6-10的运行结果如下。 函数内是局部变量:26.0 函数外是全局变量:0 6.关键字global和nonlocal 当内部作用域想修改外部作用域的变量时,就要用到global关键字。在函数内部,既可以使用global关键字来声明使用外部全局变量,也可以使用global关键字直接定义全局变量。 【实例6-11】演示在函数内声明与修改全局变量num 实例6-11的代码如下所示。 def fun1(): global num #需要使用global关键字声明 num = 2 print("函数内部1:",num) num = 5 print("函数内部2:",num) fun1() print("函数外部1:",num) num = 8 print("函数外部2:",num) 实例6-11的运行结果如下。 函数内部1:2 函数内部2:5 函数外部1:5 函数外部2:8 如果要修改嵌套作用域中的变量则需要使用nonlocal关键字。 【实例6-12】演示修改嵌套作用域中的变量 实例6-12的代码如下所示。 def outer(): num = 10 print("外层访问1:",num) def inner(): nonlocal num # nonlocal关键字声明 num = 100 print("内层访问:",num) inner() print("外层访问2:",num) outer() 实例6-12的运行结果如下。 外层访问1:10 内层访问:100 外层访问2:100 通过函数参数传递,在函数内部输出函数外部定义的全局变量。 【实例6-13】演示通过函数参数传递的方法在函数内部输出函数外部的全局变量 实例6-13的代码如下所示。 x = 9 print("函数外部输出变量的值:",x) def test(x): x = x + 1 print("函数内部输出变量的值:",x) test(x) 实例6-13的运行结果如下。 函数外部输出变量的值:9 函数内部输出变量的值:10 但如果在函数内部直接输出函数外部定义的全局变量,会出现异常。以下代码运行时会出现异常信息。 x = 9 def test(): x = x + 1 print(x) test() 出现的异常信息如下。 Traceback (most recent call last): File "D:/PycharmProject/Practice/Unit06/p6-13.py", line 11, in test() File "D:/PycharmProject/Practice/Unit06/p6-13.py", line 9, in test x = x + 1 UnboundLocalError: local variable 'x' referenced before assignment 产生“局部作用域引用错误”的原因是:test()函数中的变量x的作用域是局部作用域,未定义的变量无法引用。 6.6.2 类成员的访问限制 类成员的访问位置一般有3处:类内部的方法外、类内部的方法内、类外部。 类成员的访问方式一般有3种:通过类名称访问、通过类实例名称访问、通过类实例名称_类名称访问。 在类的内部可以定义属性和方法,而在类的外部则可以直接调用属性和方法来操作数据,从而隐藏了类内部的复杂逻辑。在类外部通过类名称或实例名称都可以直接访问类的公有属性。为了保证类内部的某些属性和方法不被外部随意访问或修改,可以在属性或方法名前面添加单下画线、双下画线或首尾都加双下画线。 Python并没有像C#、Java那样使用public、protect、private等关键字来明确限制公有属性、保护属性和私有属性,而是通过属性命名方式来区分。 (1)首尾双下画线表示定义特殊方法,一般是Python本身定义的名称,例如__init__()。 (2)以单下画线开头的表示保护(protected)类型的成员,例如_testProtectedAttribute。保护类型的成员只允许类本身和子类进行访问,即在类内部的方法外部或方法内部,类外部的实例都允许访问,但不能使用“from module import * ”语句导入,也就是跨模块不能访问保护类型的成员。 (3)以双下画线开头的表示私有(private)类型的成员,只允许定义该成员的类本身进行访问,而且也不能通过类的实例进行访问,但是可以通过“类实例名称+_类名称”方式进行访问。 例如,如果类中定义了“__age”这个类属性,其中属性“__age”的名称由双下画线开头,声明该属性为类的私有属性,该属性就不能在类的外部直接访问或被使用。但在类内部可以访问,在类内部的方法中使用私有属性时的基本语法格式为“,Person.__age”或“self.__code”。 【实例6-14】演示各种类成员的访问限制 实例6-14的代码如电子活页6-7所示。 实例6-14的运行结果如下。 类的方法内部使用'类名称.属性名称'的形式访问: 姓名:李明 性别:男 年龄:19 类的方法内部使用'self.属性名称'的形式访问: 姓名:李明 性别:男 年龄:19 类外使用'类名称.属性名称'的形式访问: 姓名:李明 性别:男 类外使用'实例名称.属性名称'的形式访问: 姓名:李明 性别:男 类外使用'类实例名称._类名称__XXX'的形式访问: 年龄:19 从实例6-14的运行结果可以看出,类内的方法内部可以通过“类名称.成员名称”和“self.成员名称”的形式访问私有成员。但在类的外部“类名称.成员名称”“实例名称.成员名称”“self.成员名称”这3种形式都不能访问私有成员。只能通过“类实例名称._类名称__XXX”方式访问私有成员,即在“类名称+私有成员名称”之前加单下画线“_”。 【实例6-15】演示定义与访问拥有不同访问权限的类属性与方法 实例6-15的代码如电子活页6-8所示。 1.创建父类的实例对象goods 代码如下。 goods =Commodity() 2.通过父类名称Commodity访问父类的属性与方法 代码如下。 print(Commodity.testPublicAttribute) print(Commodity._testProtectedAttribute) Commodity.printLine() Commodity._printStar(goods) Commodity.printPrivateParent(goods) 运行结果如下。 Public:公有属性 Protected:保护属性 Public:公有方法 ────────────── Protected:保护方法 ☆☆☆☆☆☆☆☆☆ Private:私有属性 类外部父类的私有属性无法访问,执行代码“print(Commodity.__testPrivateAttribute)”会出现以下异常信息。 AttributeError: type object 'Commodity' has no attribute '__testPrivateAttribute' 类外部父类的实例属性无法访问,执行代码“print(Commodity.commodityPrice)”会出现以下异常信息。 AttributeError: type object 'Commodity' has no attribute 'commodityPrice' 类外部父类的私有方法无法访问,执行代码“Commodity.__printTriangle(goods)”会出现以下异常信息。 AttributeError: type object 'Commodity' has no attribute '__printTriangle' 3.通过父类的实例名称goods访问父类的属性与方法 代码如下。 print(goods.testPublicAttribute) print(goods._testProtectedAttribute) print(goods._Commodity__testPrivateAttribute) modityPrice=79999.00 print("父类实例名称访问实例方法中定义的实例属性:"+str(modityPrice)) goods.printLine() goods._printStar() goods._Commodity__printTriangle() goods.printPrivateParent() 运行结果如下。 Public:公有属性 Protected:保护属性 Private:私有属性 父类实例名称访问实例方法中定义的实例属性:79999.0 Public:公有方法 ────────────── Protected:保护方法 ☆☆☆☆☆☆☆☆☆ Private:私有方法 △△△△△△△△△△△△ Private:私有属性 4.创建子类的实例对象book 代码如下。 book = Book() 5.通过子类名称Book分别访问父类与子类的属性、方法 代码如下。 print(Book.testPublicAttribute) print(Book._testProtectedAttribute) Book.printLine() Book._printStar(book) Book.printProtectedSubclass(goods) Book.printPrivateSubclass(goods) 运行结果如下。 Public:公有属性 Protected:保护属性 Public:公有方法 ────────────── Protected:保护方法 ☆☆☆☆☆☆☆☆☆ 子类内部允许访问父类的保护属性 Protected:保护属性 子类内部无法访问父类的私有属性 通过子类名称Book在类外部无法访问父类的私有属性__testPrivateAttribute、父类实例方法中定义的实例属性commodityPrice、父类私有方法__printTriangle(),子类内部也无法访问父类的私有属性__testPrivateAttribute,如果执行以下代码,会出现异常信息。 print(Book.__testPrivateAttribute) print(modityPrice) Book.__printTriangle(goods) print(Book.__testPrivateAttribute) 6.通过子类的实例名称book分别访问父类与子类的属性、方法 代码如下。 print(book.testPublicAttribute) print(book._testProtectedAttribute) print(book._Commodity__testPrivateAttribute) modityPrice=2699.00 print("子类实例访问父类实例方法中定义的实例属性:"+str(modityPrice)) book.printLine() book._printStar() book._Commodity__printTriangle() book.printProtectedSubclass() book.printPrivateSubclass() 运行结果如下。 Public:公有属性 Protected:保护属性 Private:私有属性 子类实例访问父类实例方法中定义的实例属性:2699.0 Public:公有方法 ────────────── Protected:保护方法 ☆☆☆☆☆☆☆☆☆ Private:私有方法 △△△△△△△△△△△△ 子类内部允许访问父类的保护属性 Protected:保护属性 子类内部无法访问父类的私有属性 但执行以下访问形式会出现异常。 print(book._Book__testPrivateAttribute) book._Book__printTriangle() 【任务6-7】 完整定义与使用1个父类(Commodity)和2个子类(Book、Handset) 【任务描述】 (1)在项目Unit06中创建Python程序文件6-7.py。 (2)在程序文件6-7.py中完整定义与使用1个父类(Commodity)和2个子类(Book、Handset)。 (3)综合应用类的属性与方法计算和输出应付金额、返现金额、优惠金额、运费和实付金额。 【任务实施】 在PyCharm项目Unit06中创建Python程序文件6-7.py。在程序文件6-7.py中编写程序代码,实现所需功能。父类Commodity的定义代码如电子活页6-9所示。 子类Book的定义代码如电子活页6-10所示。 子类Handset的定义代码如电子活页6-11所示。 针对创建的类Commodity和两个子类Book、Handset实施以下各项操作。 1.创建子类Book的实例对象book 代码如下。 book=Book() 2.通过类的实例对象book给类的属性赋值 代码如下。 book.code="12563157" book.name="给Python点颜色 青少年学编程" book.price=59.80 book.quantity=1 book.publisher="人民邮电出版社" book.edition=1 3.通过类的实例对象book以模拟表格方式输出图书数据 代码如下。 book.printField() book.printData() 运行结果如下。 商品编号 商品名称 价格 出版社名称 版次 12563157 给Python点颜色 青少年学编程 59.80 人民邮电出版社 1 4.通过类的实例对象book分别设置父类实例属性的值和用户等级 代码如下。 book.quantity=5 rank="Ordinary users" 5.调用类的多个方法分别计算应付金额、返现金额、优惠金额、运费和实付金额 代码如下。 discountPrice=book.getDiscountPrice(rank,book.price) discountAmount=book.quantity*discountPrice discount=book.getDiscount(book.quantity,book.price) cashback=book.getCashback(book.quantity,book.price) discountTotal=discount+cashback payable=discountAmount-discountTotal carriage=book.getCarriage(payable) payable+=carriage 6.调用子类book的方法printSettlementData()输出购物结算数据 代码如下。 book.printSettlementData(discountAmount,carriage,cashback,discount,payable) 运行结果如下。 应付金额: 275.08 运费: 0.00 返现金额:- 100.00 优惠金额:- 15.00 实付金额: 160.08 7.创建子类Handset的实例对象handset 代码如下。 handset=Handset() 8.通过子类的实例名称handset为类的实例属性赋值 代码如下。 handset.code="100010262414" handset.name="华为MateBook X Pro" handset.price=13699.00 handset.quantity=1 handset.screenSize="13.9英寸" handset.resolution="3000×2000像素" 9.通过子类的实例名称handset调用子类Handset的重构方法输出手机数据 代码如下。 handset.printField() handset.printData() 运行结果如下。 商品编号 商品名称 价格 屏幕尺寸 物理分辨率 100010262414 华为MateBook X Pro 13699.00 13.9英寸 3000×2000像素总结评价 本单元主要学习创建类及其对象,类属性与实例属性,实例方法、类方法与静态方法,类的构造方法与析构方法,类的继承与方法重写,命名空间与类成员的访问限制。 展开更多...... 收起↑ 资源预览