继承

复习

1.类

对象属性的查找循序,先找自身再找类
1.类的名称空间:直接写在类中
   2.对象的名称空间:写在__init__方法中,第一个参数一定接收类,建议只拿类来调用
   3.类的方法:在类中用@classmethod装饰的方法,第一个参数一定接受类,建议只拿类来调用
   4.对象方法:在类中定义的普通方法,第一个参数一定接收对象,建议只拿对象调用

2.封装

封装:对外隐藏属性与方法的实现细节,类的内部均可以直接访问__名字
方式:在属性或方法前用__装饰,将__名字更名为_类__名字
作用:有些属性或方法只提供给内部使用,所有采用封装处理
对象属性的封装,对外提供接口
装饰器classmethod的本质就是
def classmethod(fn)
def inner(*args,**kwargs)
t=args[0]
args[0] = t.__class__
pass
return inner

3.组合


组合的本质就是自定义类的对象作为另一个类的属性
class Teacher:
   def __init__(self, name, age):
       self.name = name
       self.age = age
t1 = Teacher("Owen", 17)
print(type(t1.name), type(t1.age))


class Student:
   # 学生可以有 老师 属性
   def __init__(self, name, age, teacher):
       self.name = name
       self.age = age
       # 自定义类的对象作为类的属性:组合
       self.teacher = teacher
# 创建一个学生
stu = Student('Bob', 18, t1)
print(stu.__dict__)

# 学生的老师年龄和姓名
print(stu.name)
print(stu.teacher)
print(stu.teacher.name)
print(stu.teacher.age)

4.继承


将所有的属性与方法抽离出,形成父类
父类是多个有共同点的普通类抽离共有属性和方法形成的类
class People
def __init__(self,name)
self.name = name

def eat(self)
print(self.name + '在吃饭')

class Student(People)
identify = '学生'

student=Student('Bob')
student.eat()

Student继承父类People的属性和方法,但是也可以有自己独有的属性或方法,如identify

#继承关系
1.父类的所有未封装的属性和方法,子类都能访问
2.父类的所有封装的属性和方法,子类都不能访问
————在外界通过子类或子类对象,也不能访问
————在子类内部也不能访问
#继承关系下的属性查找顺序
1.优先找自身,自身没有找父类
   2.分类没有找父类的父类
   3.一直找到最顶级的父类,如果还没有就报错。
#两个名词
   抽离:先写子类抽离出父类
   派生:先写父类派生出子类  
# 方法的重写
先写好父类的方法,由于父类方法的功能不能满足子类要求,子类就可以重写父类方法。
   重写方法:方法名与父类相同,自定义方法的实现体。(其实就是优先于父级访问自身同名的方法)
class Sup:
   num = 10
   def test(self):
       print('test sup')
class Sub(Sup):
   def test(self):
       print('test sub')
Sub().test()
#方法的重用
重用:还需要父类方法的功能,在父类方法功能基础上添加新功能
   突破点:在子类中调用父类的方法,还有保证调用者就是子类(子类的对象)
#针对类中普通的方法
#方法一:super
class Sup:
   def test(self):
       print('>>>sup', self)
       print('test sup')
class Sub(Sup):
   pass
   def test(self):
       # Sup().test()
       # python2中写法
       # super(Sub, self).test()
       # python3中简化写法
       super().test()
       print('>>>sub', self)
       print('test sub')
Sub().test()
#方法二,直接调用,与继承没有关系,同样使用对象的绑定
class Sup:
   def test(self):
       print('>>>sup', self)
       print('test sup')
class Sub(Sup):
   pass
   def test(self):
       Sup.test(self)
       print('>>>sub', self)
       print('test sub')
Sub().test()
#================针对类中的__init__方法==================
以上面相同,有两种
#方法一、super
人类:只需要初始化 - name
老师: 要初始化 - name salary
学生: 要初始化 - name grade
class Sup:
   def test(self):
       print(self)
   def __init__(self,name)
  self.name = name

class Sub(Sup)
#有继承关系下,只要名字相同,即时产生不同,还是属于同一个方法
   def test(self,num)
  super().test()
       print(num)
   
   #默认父级的__init__可以被继承过来
   #但是会被出现子类对象的属性比父类多
   
   def __init__(self,name,salary)
  super().__init__(name)#父级有的共性功能能通过super()交给父级做
       self.salary = salary#子类特有的自己来完成
#方法二,直接调用
class Sup:
   def test(self):
       print(self)
   def __init__(self, name):
       self.name = name
class Sub(Sup):
   def test(self, num):
       Sup.test(self)
       print(num)
   def __init__(self, name, salary):
       Sup.__init__(self,name)
       self.salary = salary
多继承
经典类:没有继承任何类的类(python2中存在,因为没有像python3一样,当没有父级时默认object为父级。)
   新式类:python2中要直接或间接继承object的类,而python3中所定义的所有类都是新式类(默认最高级是父级)
经典类:深度查找,就是查找到最高级后,再去广度查找
新式类:广度查找,广度自左向右查询结束后,再去查最高级,其实依照MRO列表中的顺序自左向右查询(只有在新式类找那个有)

 

posted @ 2019-04-19 16:17  Mr-Bear  阅读(152)  评论(0编辑  收藏  举报