内容正文:
筐鱼梧领凤峡匪跑脚凡辅乒踪勿久褂舟婴袭剪肚爹伦甄啸镣娟附卉态再骂广东农工商职业技术学院PPT模板-精美原创毕业论文答辩广东农工商职业技术学院PPT模板-精美原创毕业论文答辩
项目9 继承与多态
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目介绍
项目背景
面向对象的程序设计思想,相较于面向过程的程序设计思想,除了实现了封装,另一大优势就是实现了重用。传统的重用,基本上就是代码的拷贝和修改,不仅功能上受到限制,且容易出错。面向对象通过类之间的继承与多态,使得重用不再是简单的代码拷贝。类的重用技术通过创建新类来复用已有的代码,而不必从头开始编写,可以使用系统标准类库、开源项目中的类库、自定义类等已经调试好的类,从而降低工作量并减少错误的可能性。
项目介绍
项目背景
类的重用主要有两种方法:类的继承与类的组合。其中,类的继承是指在现有类的基础上创建新类,在新类中添加代码,以扩展原有类的属性(数据成员)和方法(成员函数),并且还有重写和多态等方式。类的组合是指在新创建的类中包含有已有类的对象作为其属性。
项目介绍
项目规划
01
熟悉类的继承与多态概念和使用方法
02
熟悉类的组合概念和使用方法
03
能综合运用类的继承、多态、组合等方法解决典型程序设计问题
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目目标
知识目标
1
熟悉类的继承与多态的概念
2
熟悉类的组合概念
3
了解基于类的重用方法解决问题的方法
项目目标
能力目标
1
熟练运用类的继承与多态的使用方法
2
熟练运用类的组合使用方法
3
能够基于类的重用方法解决实际问题
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目准备
1. 类的继承
继承是在一个被作为父类(或称为基类)的基础上扩展新的属性和方法来实现的。父类定义了公共的属性和方法,继承父类的子类自动具备父类中的非私有属性和非私有方法,不需要重新定义父类中的非私有内容,并且可以增加新的属性和方法。
项目准备
1. 类的继承
Python中,所有类的最终父类是object类,所有类最顶层的根都是object类。在程序中创建一个类时,除非明确指定父类,否则默认从Python的根类object继承。Python中的一个类可以有多个父类,同时从多个父类中继承所有特性。
项目准备
1. 类的继承
类继承的语法如下:
1)继承的实现
class ChildClassName(ParentClassName1[, ParentClassName2[,ParentClassName3, …]]):
#类体或pass语句
项目准备
1. 类的继承
子类继承父类中的非私有属性,但不能继承父类的私有属性,也无法在子类中访问父类的私有属性。子类只能通过父类中的公有方法访问父类中的私有属性。
2)类属性的继承
#product.py
#coding=gbk
class Product(object):
id = 0 #类属性
def __init__(self,name,color,price):
Product.id=Product.id+1
self.name=name #公有实例属性
self.color=color #公有实例属性
self.__price=price #私有实例属性
def setPrice(self,price):
self.__price=price
def getPrice(self):
return self.__price
#laptop.py
class Laptop(Product):
def __init__(self,name,color,price,cpu):
super(MobilePhone,self).__init__(name,color,price)
self.networkstandard=networkstandard
#继承了父类中的公共属性,可以直接访问
print('A Laptop has been created. the name is', self.name)
print('产品编号: '+str(self.__class__.id)) #继承父类中的类属性,可以直接访问
#print('The price is ' + str(self.__price)) #无法继承父类中的私有属性,不能在子类中直接访问
print('The price is ' + str(self.getPrice())) #可以通过父类中的公有方法访问私有属性
def main():
m= Laptop ("Huawei",Silver,6000,'Core i5')
print("产品名称:"+m.name+",产品价格:"+str(m.getPrice()))
print(Laptop.id) #调用从父类中继承的类属性
if __name__ == "__main__":
main()
项目准备
1. 类的继承
父类与子类如果定义了名称相同的属性,父类中的属性在子类中将被覆盖。
3)类属性的覆盖
#laptop_override.py
#coding=gbk
from product import Product
class Laptop(Product):
def __init__(self,name,color,price,cpu):
super(MobilePhone,self).__init__(name,color,price)
self.networkstandard=networkstandard
self.color='The color defined in the sub class. ' #子类中的属性color覆盖父类中的同名的属性
#继承了父类中的公共属性,可以直接访问
print('A Laptop has been created. the name is', self.name)
print('产品编号: '+str(self.__class__.id))
#print('The price is ' + str(self.__price))
print('The price is ' + str(self.getPrice()))
def main():
m= Laptop ("Huawei",Silver,6000,'Core i5')
print("产品名称:"+m.name+",产品价格:"+str(m.getPrice()))
print(m.color) # 调用子类中的属性
print(Laptop.id)
if __name__ == "__main__":
main()
项目准备
1. 类的继承
子类继承父类中的非私有方法,不能继承私有方法。
4)类方法的继承
# product_method.py
#coding=gbk
class Product(object):
id = 0 #类属性
def __init__(self,name,color,price):
Product.id=Product.id+1
self.name=name #公有实例属性
self.color=color #公有实例属性
self.__price=price #私有实例属性
def setPrice(self,price):
self.__price=price
def getPrice(self):
return self.__price
@staticmethod #声明静态,去掉则编译报错; 静态方法不能访问实例属性
def testStaticMethod(): #使用了静态方法,则不能再使用self
print("The static method is called.")
@classmethod #类方法
def testClassMethod(cls):
print("The class method is called.")
# laptop_method.py
class Laptop(Product):
def __init__(self,name,color,price,cpu):
super(MobilePhone,self).__init__(name,color,price)
self.networkstandard=networkstandard
self.color='The color defined in the sub class. ' #子类中的属性color覆盖父类中的同
名的属性
#继承了父类中的公共属性,可以直接访问
print('A Laptop has been created. the name is', self.name)
print('产品编号: '+str(self.__class__.id))
#print('The price is ' + str(self.__price))
print('The price is ' + str(self.getPrice()))
self.testStaticMethod() #访问继承自父类的静态方法
self.testClassMethod() #访问继承自父类的类方法
def main():
m= Laptop ("Huawei",Silver,6000,'Core i5')
print("产品名称:"+m.name+",产品价格:"+str(m.getPrice()))
print(m.color) # 调用子类中的属性
MobilePhone.testStaticMethod()
MobilePhone.testClassMethod()
if __name__ == "__main__":
main()
项目准备
1. 类的继承
当子类中定义了与父类中同名的方法时,子类中的方法将覆盖父类中的同名方法,也就是重写了父类中的同名方法。
5)类方法的重写
# laptop_method_override.py
#coding=gbk
from product_method import Product
class Laptop(Product):
def __init__(self,name,color,price,cpu):
super(MobilePhone,self).__init__(name,color,price)
self.networkstandard=networkstandard
self.color='The color defined in the sub class. ' #子类中的属性color覆盖父类中的同
名的属性
#继承了父类中的公共属性,可以直接访问
print('A Laptop has been created. the name is', self.name)
print('产品编号: '+str(self.__class__.id))
#print('The price is ' + str(self.__price))
print('The price is ' + str(self.getPrice()))
self.testStaticMethod() #访问继承自父类的静态方法
self.testClassMethod() #访问继承自父类的类方法
def totalPrice(self,number): #定义与父类中同名的方法
print('The totalPrice method in the sub class is called.')
#super(MobilePhone,self).totalPrice(number)
def main():
m= Laptop ("Huawei",Silver,6000,'Core i5')
print("产品名称:"+m.name+",产品价格:"+str(m.getPrice()))
print(m.color) # 调用子类中的属性
MobilePhone.testStaticMethod()
MobilePhone.testClassMethod()
#调用子类中的方法,因为子类覆盖了父类中同名的方法
m.totalPrice(2)
if __name__ == "__main__":
main()
项目准备
1. 类的继承
(1)子类不定义新的构造函数。
如果子类的初始化方法没有覆盖父类的初始化方法__init__(),则在创建子类对象时,默认执行父类的初始化方法。
6)继承关系下的初始化方法
项目准备
1. 类的继承
(2)子类定义新的构造函数。
当子类中的初始化方法__init__()覆盖了父类中的初始化方法时,创建子类对象时,执行子类中的初始化方法,不会自动调用父类中的初始化方法。
6)继承关系下的初始化方法
项目准备
1. 类的继承
(3)子类调用父类构造方法。
Python中编译器不会自动插入对父类初始化方法的调用。如果需要调用父类的初始化方法,必须在子类的初始化方法中明确写出调用语句。有两种调用方法:
父类名.__init__(self, 其他参数);
super(本子类名, self)__init__(其他参数)。
注意,这里的其他参数是指初始化方法定义时列出的除self外的参数。
6)继承关系下的初始化方法
项目准备
1. 类的继承
Python允许多重继承,即一个子类有多个父类,子类同时获得多个父类的属性和方法
7)多重继承
class Product(object): #新式类
def testClassicalClass(self):
print('执行Product类中的testClassicalClass()方法')
class Laptop(Product):
def testMethod(self):
print('执行Laptop类中的testMethod()方法')
class Pad(Product):
def testClassicalClass(self):
print('执行Pad类中的testClassicalClass()方法')
class Ultrabook(Laptop, Pad):
def testMethod(self):
print('执行Ultrabook类中的testMethod()方法')
def main():
u = Ultrabook ()
u.testClassicalClass()
if __name__ == "__main__":
main()
项目准备
2. 类的组合
类的组合(composition)是类的另一种重用方式。如果程序中的类需要使用其他类的对象,就可以使用类的组合方式。组合关系可以用“has-a”关系来表达,就是一个主类中包含其他对象。
在继承关系中,父类的内部细节对于子类来说在一定程度上是可见的。所以通过继承的代码复用可以说是一种“白盒式代码复用”。在组合关系中,对象之间各自的内部细节是不可见的,所以通过组合的代码复用可以说是一种“黑盒式代码复用”。
1)类的组合的实现
项目准备
2. 类的组合
在组合关系下有两种方法可以实现对象属性初始化。第一种方法是通过组合类初始化方法传递被组合对象所属类的初始化方法中的参数;第二种方法是在主程序中创建被组合类的对象,然后将这些对象传递给组合类。如下面代码,左侧代码使用了第一种方法,右侧代码使用了第二种方法。
2)类的组合的对象初始化
class Engine(object):
def __init__(self, displacement):
self. displacement= displacement
class Gearbox(object):
def __init__(self, position):
self.position = position
class Car(object):
def __init__(self, displacement, position):
self.engine = Engine(displaySize)
self.gearbox = Gearbox(memorySize)
def main():
c = Car(2.0,6)
if __name__ == "__main__":
main()
class Engine(object):
def __init__(self, displacement):
self. displacement= displacement
class Gearbox(object):
def __init__(self, position):
self.position = position
class Car(object):
def __init__(self, engine , gearbox ):
self.engine = engine
self.gearbox = gearbox
def main():
engine = Engine(2.0)
gearbox = Gearbox(6)
c = Car(engine, gearbox)
if __name__ == "__main__":
main()
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目实施
任务9.1 调用父类及父类的父类的构造器
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。列表带有很多操作方法,reverse倒序就是其中一个,本次实验通过调用reverse来了解python中的列表。
项目实施
任务9.1 调用父类及父类的父类的构造器
建立 “调用父类及父类的父类的构造器.py”文件,用于编写Python实验程序
编写任务代码
# 定义Animal类,并定义其构造器
class Animal:
def __init__(self):
print('Animal')
# 定义Horse类,继承Animal类,定义其构造器,在其构造器中调用父类的构造器
class Horse(Animal):
def __init__(self):
super().__init__()
print('Horse')
# 定义Donkey类,继承Animal类,定义其构造器,在其构造器中调用父类的构造器
class Donkey(Animal):
def __init__(self):
super().__init__()
print('Donkey')
# 定义Mule类,继承Horse与Donkey类,定义其构造器,在其构造器中调用父类的构造器
class Mule(Horse, Donkey):
def __init__(self):
super().__init__()
print('Mule')
# 创建Mule类的实例
if __name__ == '__main__':
mule = Mule()
项目实施
任务9.1 调用父类及父类的父类的构造器
执行程序
①用鼠标右键单击右侧编辑窗口,在菜单中选择“Run ‘python主程序所在文件名’”一项执行编写好的Python程序,本次实验文件名为“调用父类及父类的父类的构造器”
②在IDE下方控制台查看输出结果
课后练习与技能训练
一、填空题
练习
1.通过 ,可以基于已有类创建新的类,新类除了继承已有类的所有属性和方法,还可以根据需要增加新的属性和方法。
2.通过 ,可以使得在执行同一条语句时,能够根据实际使用的对象类型决定调用哪个方法。
3.如果一个类C1通过继承已有类C而创建,则将C1称作 ,将C称做基类、父类或超类。
4.如果一个子类只有一个父类,则将这种继承关系称为 ;如果一个子类有两个或更多父类,则将这种继承关系称为 。
课后练习与技能训练
一、填空题
练习
5. 是指子类可以对从父类中继承过来的方法进行重新定义,从而使得子类对象可以表现出与父类对象不同的行为。
6.内置函数 用于判断一个对象所属的类是否是指定类或指定类的子类。
7.内置函数 用于判断一个类是否是另一个类的子类。
8.内置函数 用于获取一个对象所属的类。
课后练习与技能训练
二、选择题
练习
1.关于super方法的说法说法错误的是()
A.super方法用于获取父类的代理对象,以执行已在子类中被重写的父类方法。
B.super方法有两个参数:第一个参数是要获取父类代理对象的类名。
C.在一个类A的定义中调用super方法时,可以将两个参数都省略,此时,super()等价于super(A, self)。
D.第二个参数必须传入对象名,该对象所属的类必须是第一个参数指定的类或该类的子类,找到的父类对象的self会绑定到这个对象上。
课后练习与技能训练
二、选择题
练习
2.下图类的继承关系中,说法错误的是()
A.Student类和Teacher类都是Person类的子类
B.Person类是其他3个类的父类
C.Student类是Person类的子类,又是TA类的父类
D.TA类有两个父类,这种关系称为多重继承
课后练习与技能训练
三、简答题
练习
1.写出下面程序的输出结果。
class Person:
def __init__(self,name):
self.name=name
def Display(self):
print(self.name)
class Student(Person):
def __init__(self,sno,name):
super().__init__(name)
self.sno=sno
def Display(self):
super(Student,self).Display()
print(self.sno)
if __name__=='__main__':
per=Person("张三")
per.Display()
stu=Student(78,"李四")
stu.Display()
课后练习与技能训练
三、简答题
练习
2.写出下面程序的输出结果。
class Person:
pass
class Student(Person):
pass
if __name__=='__main__':
per=Person()
stu=Student()
print("stu所属类是Person类的子类",isinstance(stu,Person))
print("Student类是Person类的子类",issubclass(Student,Person))
print("per所属类是Studnet类的子类",isinstance(per,Student))
print("Person类是Student类的子类",issubclass(Person,Student))
print('stu对象所属的类:', type(stu))
print('per对象所属的类:', type(per))
$$