'''
1、什么是组合
组合就是一个类的对象具备某一个属性,该属性的值是指向另外外一个类的对象
2、为何用组合
组合也是用来解决类与类直接代码冗余问题的
3、如何用组合
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))
stu1=OldboyStudent('猪哥',19,'male',1)
tea1=OldboyTeacher('egon',18,'male',10)
stu1.choose_course()
tea1.score(stu1,100)
print(stu1.__dict__)
'''
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 = "oldbay"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def __init__(self,name,age,sex,claid):
OldboyPeople.__init__(self,name,age,sex)
self.claid=claid
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)#调用Course,产生python
linux=Course("linux运维","5mons",800)
# python.tell_info()
#创造老师学生
stu1=OldboyStudent("yf",18,"male",32)
tea1=OldboyTeacher("egon",18,"male",10)
#将学生、老师与课程关联组合
# name = input("请输入课程:").strip()
stu1.course=python#将stu1的对象里添加新的属性course=print,增加属性后,在stu1里能看见python
print(stu1.__dict__)#显示该学生对象下面的所有属性,可以看见python的内存地址
stu1.course.tell_info()#stu1对象调用course显示的是Course内的__init__对象内存地址,然后再调用Course内的__init__对象的
# 绑定方式tell_info(),就跟stu1调用自己的绑定方式一样,体现结果
stu1.course=linux
tea1.course=python
tea1.course.tell_info()
'''
1、菱形继承
当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承
2、菱形继承的问题:
python2区分经典类与新式类,如果子的继承是一个菱形继承,那么经典类与形式的区别为?
经典类下查找属性:深度优先查找
新式类下查找属性:广度优先查找
'''
class G(object):
def test(self):
print('from G')
pass
class E(G):
# def test(self):
# print('from E')
pass
class B(E):
# def test(self):
# print('from B')
pass
class F(G):
# def test(self):
# print('from F')
pass
class C(F):
# def test(self):
# print('from C')
pass
class D(G):
# def test(self):
# print('from D')
pass
class A(B,C,D):
# def test(self):
# print('from A')
pass
obj=A()
#print(A.mro())#只有python3中才有查看继承顺序的顺序
obj.test() #A->B->E-C-F-D->G-object
一共有三种构造继承模式
1、是直线型,子类内对象,子类,父类,后面再跟父类的父类
2、并非像菱形一样最后都汇到最顶层父类的,先从子类内对象,子类,然后是依次从左边到最顶端父类,再往右下一个父类到最顶端的方式
3、菱形继承,唯一体现新式类与经典类区别:
#经典类只有在python2不继承object的是深度优先类型,一条道走到黑
#新式类是python3,因为python3中无论是否继承object,也是自带继承object,称为广式优先类型,知道最后一步才去最顶层父类
#当python2中的最顶层的父类加上object时就成为新式类
#在子派生的新方法中重用父类功能的两种方式
#方式一:与继承无关
# 指名道姓法,直接用:类名.函数名
# 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)
# 方式二:严格以来继承属性查找关系
# super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
#super()会为当前类的下一类进行查找
# super().__init__(不用为self传值)
# 注意:
# super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super()
# 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)
# super(OldboyStudent,self).__init__(name,age,sex)
# self.stu_id=stu_id
#
# def choose_course(self):
# print('%s is choosing course' %self.name)
#
#
# stu1=OldboyStudent('猪哥',19,'male',1)
# print(stu1.__dict__)
#
# print(OldboyStudent.mro())
# class A:
# def f1(self):
# print("A.f1")
# class B:
# def f2(self):
# super().f1()
# print("B.f2")
# class C(B,A):
# pass
#
# obj=C()
# obj.f2()
# print(C.mro())#C->B->A->object
#按照这个继承关系,先从C的对象中找,不存在,再去C类中找
#不存在,再去B类中找,找到了,调用,出现里面super当前类的下一个类查找
#显示A.f1然后再打印B类中的B.f2
'''
1 什么是多态
多态指的是同一种事物的多种形态
水-》冰、水蒸气、液态水
动物-》人、狗、猪
2 为和要用多态
多态性:
继承同一个类的多个子类中有相同的方法名
那么子类产生的对象就可以不用考虑具体的类型而直接调用功能
3 如何用
'''
# import abc
# class Animal(metaclass=abc.ABCMeta):
# @abc.abstractmethod
# def speak(self):
# print("看我")
# @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()
# #
# #
# peo1.speak()
# dog1.speak()
# pig1.speak()
#
# def my_speak(animal):
# animal.speak()
#
# my_speak(peo1)
# my_speak(dog1)
# my_speak(pig1)
#相同事物的使用可以统一类内的函数名称一样,便于使用调用,父类只是一个制定标准,并无软用
# 而子类统一函数名后,可以用一个函数统一输出,只要子类的对象放入就会显示结果,更加的方便便利
# l=[1,2,3]
# s='helllo'
# t=(1,2,3)
#
# print(l.__len__())
# print(s.__len__())
# print(t.__len__())
#
# # def len(obj):
# # return obj.__len__()
#
# print(len(l)) # l.__len__()
# print(len(s)) #s.__len__()
# print(len(t))
class Disk:
def __init__(self,age):
self.age=age
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("sb")
obj2=Process()
obj3=File()
def m_read(aimi):
aimi.read("q")
aimi.write()
#通过函数的调用,只要每次把对象传入,就可以直接把内容全部显示,有个局限性,
# 是必须函数没有要额外传入的值,才行的同,不然函数不然整体控制的函数不能用
m_read(obj1)
m_read(obj2)
m_read(obj3)