组合,菱形继承,子类重用父类2,深度广度查找

'''
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)

posted @ 2018-06-27 15:39  指尖市场  阅读(140)  评论(0编辑  收藏  举报