对象3 继承查找 多态 组合

单继承下的属性查找

先从自己的对象里面查找,如果没查到,再去自己的类里面找,如果没找到,再去父类里面查找。单继承下会一直遵循这个原则。

class Foo:
  def f1(self):
    print('Foo.f1')
    
    
  def f2(self):
    print('Foo.f2')
    self.f1()  # self ==> obj
    
    
class Bar(Foo):
  def f1(self):
    print('Bar.f1')
    
    
    
obj = Bar()
obj.f2()

#输出结果: Foo.f1
#	             Bar.f1 

# 因为self谁调用 self就是谁 一旦知道这个,就遵循先找自己里面的再找父类的原则 那Bar里面是有f1的 所以,第二次的f1 输出结果是Bar里面的f1
class Foo:
  def __f1(self): # ==>_Foo__f1
    print('Foo.f1')
    
    
  def f2(self):
    print('Foo.f2')
    self.__f1()  # ==>_Foo__f1
    
    
class Bar(Foo):
  def __f1(self): # ==>_Bar__f1
    print('Bar.f1')
    
    
obj = Bar()
obj.f2()

# 输出结果  Foo.f2
#	          Foo.f1

多继承下的属性查找

在Python2中有经典类与新式类之分

新式类:继承了object类的子类,以及该子类的子类等

经典类:没有继承object类的子类,以及该子类的子类等

在Python3中没有继承任何类,那么就会默认继承object,所以Python中全是新式类

1、继承顺序

如果继承关系为非菱形结构,那它会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

但如果继承关系是菱形结构,那么属性查找的方式有两种,分别是深度优先和广度优先!
image

image

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

而非菱形继承没有汇总的点,会将每一条分支查找完毕才会进行其他分支查找。

可以直接用下划线mro列表查找它的继承查找属性。

super与mro

class People():
  school = 'sh'
  
  def__init__(self,name,age,course = None):
    self.name = name
    self.age = age
    
    
class Student(People):
  
  def __init__(self,name,age,course)
#  	People.__init__(self,name,age)  # 指明道姓调用父类
		super().__init__(name,age) # 用super也能实现同样的效果
    self.course = course
    
    
  def choose(self):
    pass
  
  
class Teacher(People):
  
  
  def __init(self,name,age,level):
#   People.__init__(self,name,age)
		super().__init__(name,age)
    self.level = level
    

但是super()方法并不表示父类

class A():
  def test(self):
    print('A--->test')
    super().aaa()
    
    
class B():
  def test(self):
    print('B--->test')
        
  def aaa(self):
    print('B--->aaa')
    
    
class C(A,B):
  def aaa(self):
    print('C--->aaa')
    
    
c = C()
c.test()

# 如果super()	表示的是父类 按道理A的父类是object类,object类里肯定没有aaa 那就会报错
# 但实际输出结果是 A--->test
#								B--->aaa

print(C.mro()) # 输出如下
 # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

查找顺序是以mro列表算法为准的,以什么为起始查找,就以那个类的mro列表为准

多态与多态性

1、什么是多态:指的是同一种事物的多种形态

class Animal():
  pass

class Humanity(Animal):
  pass

class Dog(Animal):
  pass

class Pig(Animal):
  pass


2、为什么要有多态=>多态会带来什么样的特性,多态性

class Animal():
  def say(self):
  	print('动物的基本发声功能...')

class Humanity(Animal):
  def say(self):
    super().say()
    print('嘤嘤嘤')

class Dog(Animal):
  def say(self):
    super().say()
    print('汪汪汪')

class Pig(Animal):
  def say(self):
    super().say()
    print('哼哼哼')
    
    
    
obj1 = Humanity()
obj2 = Dog()
obj3 = Pig()

obj1.say()
obj2.say()
obj3.say()

# 输出结果为
# 动物的基本发声功能...
# 嘤嘤嘤
# 动物的基本发声功能...
# 汪汪汪
# 动物的基本发声功能...
# 哼哼哼

组合

组合:一个对象拥有一个属性,该属性是另外一个对象

解决类与类之间冗余的问题

1、继承必须满足什么是什么的关系

2、组合满足什么有什么的关系

class Foo():
  x = 1
  def __init__(self,m):
    self.m = m
    
  def func1(self):
    return self.m
  
  
  
 class Bar():
  y = 2
  def __inti__(self,n):
    self.n = n
    
    
  def func2(self):
    return self.n
  
  
obj1 = Foo(111)
obj2 = Bar(666)

obj1.z = obj2  # 将对象obj2赋值给obj1.中的新增对象
# 这样obj1就是一个超级对象 里面也包含了obj2中的属性

print(obj1.z.n)
class People():
school = 'sh' 
def __init__(self,name,age,gender)
	self.name = name    
	self.age = age    
	self.gender = genderclass Student(People): 
	school = 'sh'  
	def __init__(self,name,age,gender,course = None):  
	if course is None:     
	course = []       
	super().__init__(name,age,gender)   
	self.courses = course      
	def choose_course(self,course):    
	self.courses.append(course) 
	print('%s 选课成功 %s'%(self.name,self.courses))    class Course():  def __init__(self,course_name,course_period,course_price):    self.course_name = course_name    self.course_period = course_period    self.course_price = course_price                class Teacher(People):  school = 'sh'  def __init__(self,name,age,gender,lever):		super().__init__(name,age,gender)    self.lever = lever      def score(self,stu_obj,num):    stu_obj.num = num    print('%s老师给%s学生打了%s分'%(self.name,stu_obj.name,num))        python = Course('python','6month',2000)linux = Course('linux','5month',1188)    teach1 = Teacher('kk','20','male',10)teach1.course = linuxprint(teach1.course.course_name)# 就是将一个对象赋值给另外一个类的对象#让另一个对象里面包含该对象的功能和属性
posted @ 2021-07-14 20:02  popopop  阅读(32)  评论(0)    收藏  举报