一:组合
1,什么是组合?
组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象
2,为何用组合?
组合也是用来解决类与类之间代码冗余问题的
3,使用组合
class Course:#定义课程了类
def __init__(self,name,period,price):
self.name=name
self.period=period
self.price=price
def tell_info(self):#定义查看课程信息的一个方法
msg="""
课程名:%s
课程周期:%s
课程价钱:%s
""" %(self.name,self.period,self.price)
print(msg)
class OldboyPeople:#定义人类
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople):#定义学生类
def __init__(self,name,age,sex,stu_id):
OldboyPeople.__init__(self,name,age,sex)
self.stu_id=stu_id
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):#定义老师类
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self,name,age,sex)
self.level=level
def score(self,stu,num):
stu.score=num
print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num))
# 创造课程
python=Course('python全栈开发','5mons',3000)
linux=Course('linux运维','5mons',800)
# python.tell_info()
# linux.tell_info()
# 创造学生与老师
stu1=OldboyStudent('猪哥',19,'male',1)
tea1=OldboyTeacher('egon',18,'male',10)
# 将学生、老师与课程对象关联/组合 重点
stu1.course=python
tea1.course=linux
stu1.course.tell_info()
tea1.course.tell_info()
二:菱形继承问题
1,什么是菱形继承?
当一个子类继承多个父类时,多个父类最终继承了同一个类,称之为棱形继承
2,菱形继承问题
python2区分经典类与新式类,如果子类的继承是一个菱形继承,那么
经典类下查找属性:深度优先查找
新式类下查找属性:广度优先查找#新式类下提供了一个mro()方法用于查找mro链条
三:在子类派生新方法中重用父类功能的两种方式
在子派生的新方法中重用父类功能的两种方式
方式一:指名道姓法:直接用:类名,函数名
class OldboyStudent(OldboyPeople):
# def __init__(self,name,age,sex,stu_id):
# OldboyPeople.__init__(self,name,age,sex)#方式一
# self.stu_id=stu_id
方式二:严格按照继承属性查找关系
super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
supe().__init__(不用为self传值)
注意点:
super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super()
列如:
class OldboyStudent(OldboyPeople):
# def __init__(self,name,age,sex,stu_id):
# # OldboyPeople.__init__(self,name,age,sex)
# super(OldboyStudent,self).__init__(name,age,sex)#完整的super调用
# self.stu_id=stu_id
四:多态与多态性
1,什么是多态
多态指的是同一种事物的多种状态
水-——》冰,水蒸气,液态水
动物—————》人,狗,猪
2,为什么要用多态
多态性: 继承同一个类的多个子类中有相同的方法名
那么子类产生的对象就可以不用考虑具体的类型而直接调用功能
3,用法
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
@abc.abstractmethod
def eat(self):
pass
# Animal() #强调:父类是用来指定标准的,不能被实例化
class People(Animal):
def speak(self):
print('say hello')
def eat(self):
pass
class Dog(Animal):
def speak(self):
print('汪汪汪')
def eat(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
def eat(self):
pass
peo1=People()
dog1=Dog()
pig1=Pig()
# python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子
class Disk:
def read(self):
print('disk read')
def write(self):
print('disk wirte')
class Process:
def read(self):
print('process read')
def write(self):
print('process wirte')
class File:
def read(self):
print('file read')
def write(self):
print('file wirte')
obj1=Disk()
obj2=Process()
obj3=File()