面向对象之继承,组合

一:继承基础

【1】基础概念

(1)继承

  (1)定义:是一种定义新类的方式

  (2)继承类被称之为子类/派生类 被继承者被称为父类/基类

  例如:王思聪继承王健林的财产 那么王思聪就是属于子类 而王健林属于父类

PS:在程序中继承属于 类与类之间的关系

 

(2)作用:

  (1)子类可以继承父类中的某些属性,方法等

  (2)子类可以重复使用父类的代码 提高代码的使用量

 

(3)使用方式:

  (1)语法:class +类名(父类名称):

例如:

class Father:
    pass


class Son(Father):
    pass


print(Son.__bases__) # (<class '__main__.Father'>,)

 

【2】继承扩展:

(1)抽象:

  (1)继承描述的是一种什么是什么的关系 在继承之前必须先抽象

  (2)抽象是将多个子类具有相同属性和特征抽取出来 形成一个新的类 

  (3)继承一个已经现存的类 可以修改或者扩展原有功能

案例展示:

class Father:

    def __init__(self,name,age):
        self.name = name
        self.age = age


class Son(Father):

    def __init__(self, name, age):
        self.name = name
        self.age = age

fat = Father('爸爸',40)

son = Son('儿子',18)

print(fat.name) # 爸爸
print(son.name) # 儿子

# PS:可以看见其中有很多重复代码
抽象产生原因案例

PS:其中有大量的重复的代码 代码组织架构比较差

 

解决方法:

class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age


class Father(Person):
    print('从上述父类调用')



class Son(Person):
    print('从上述父类调用')



fat = Father('爸爸',40)

son = Son('儿子',18)

print(fat.name) # 爸爸
print(son.name) # 儿子
抽象好处

PS:其通过抽取大量相同的特征 汇总成一个新类 其余类继承这个新类 减少代码的冗余

 

(2)属性的查找顺序:

  (1)首先查找对象本身

  (2)查找对象所属的类

  (3)查找父类

  (4)查找object

例如:

class Person:
    # 类被注释
    test = '父类'



class Father(Person):

    # 对象被注释
    test = ''
    pass


fat = Father()
fat.test = '对象'
print(fat.test)  
'''
1:对象
2:类
3:父类

'''
属性查找顺序

 

(3)派生:

    (1)当一个子类出现于父类中不同的内容时候

    (2)通常子类都会出现于父类不同的内容 如果完全相同也没什么意义 

    (3)其主要是为了在继承父类属性和方法之上 扩展自己的功能

例如:

class Animal:
    def run(self):
        print('动物都喜欢跑')




class Cat(Animal):

    # 扩展的新的函数 功能
    def eat(self):
        print('猫喜欢吃鱼')


cat = Cat()

# 继承父类的行为
cat.run() # 动物都喜欢跑

# 调用新的属性
cat.eat() # 猫喜欢吃鱼

#  添加自己新的属性
cat.color = '黑猫警长'
print(cat.color) # 猫喜欢吃鱼
派生案例

 

(4)覆盖

  (1)也称之为重写

  (2)子类出现了与父类一样的东西

  (3)当对象在调用的时候会以子类的为准

例如:

class Animal:
    def run(self):
        print('动物都喜欢跑')




class Cat(Animal):
    def run(self):
        print('动物Cat都喜欢跑')

    # 扩展的新的函数 功能
    def eat(self):
        print('猫喜欢吃鱼')


cat = Cat()

# 继承父类的行为
cat.run() # 动物Cat都喜欢跑 直接查找类属性
覆盖案例

 

(4)子类调用父类的方式:

  (1)继承:即子类与父类关联比较相近的时候

  (2)super:子类与父类关联不是那么相近

  (3)指名道姓 父类名.父类方法 子类与父类关联不是那么相近

案例展示:

(1)super:

class Phone:
    def call(self,name):
        print('%s使用手机打电话'%name)

class Person(Phone):
    def run(self):
        super().call('SR')


per = Person()
per.run() # SR使用手机打电话

 

(2)指名道姓:

class Phone:
    def call(self,name):
        print('%s使用手机打电话'%name)

class Person(Phone):
    def run(self):
        Phone.call(self,'SR')


per = Person()
per.run() # SR使用手机打电话

PS:其跟继承没什么关系

 练习:如何限制一个元素类型存入空间中

例如:

# 可以直接调用list作为存储
class My_list(list):

    # 初始化定义类型
    def __init__(self,element_type):
        self.element = element_type

    def append(self, object):
        # 判断初始化类型 是否为自己要加入的 如果是则加入
        if type(object) == self.element:
            super().append(object)
        else:
            print('错误的类型')


# 调用列表作为存储空间
class My_list(list):
    # 定义初始化要加入的元素类型
    def __init__(self,element_type):
        self.element_type = element_type

    # 定义要添加的函数
    def append(self, object):
        # 判断加入的类型 是否为自己想要加入的类型
        if type(object) == self.element_type:
            super().append(object)
        else:
            print('类型错误')

# 初始化传入类型
m = My_list(int)
m.append(1)
print(m[0]) # 1

# 报错 其不是整形
m.append('123')
print(m[1]) # 类型错误
限制元素加入

 

二:组合

【1】:基础概念

(1)概念

  (1)也是一种关系 描述是什么有什么的关系

  (2)在python中将一个对象做为令一个对象的属性

 

(2)组合目的:

  (1)也是复用代码

  (2)耦合度降低 减少代码之间的影响

class Phone:
    def __init__(self,kind,price,):
        self.kind = kind
        self.price = price

    def call(self):
        print('正在通话中')

class Student:
    def __init__(self,name,phone):

        self.name = name
        self.phone = phone

        print('%s正在使用手机通话'%self.name)

pho = Phone('Apple',9999)

stu = Student('SR',pho)

stu.phone.call() # 正在通话中
组合

PS:

(1)Student想调用Phone需要将其存入自己的名称空间中

(2)当将其存入自己的名称空间时候 需要保持对象与名称空间一致 于是对象也需要传参

(3)创建对象就是实例化的过程 可以将另外一个类所对应的变量pho以参数的形式上传给类内部的函数中

(4)函数会收到该参数 然后与其交互数据

 

(3)菱形继承

  (1)新式类:

    (1)其显示或者隐式属于object的子类

    (2)在python3中全部都是新式类

  (2)经典类

    (1)不属于object的子类   

    (3)其只在python2中才会出现

 

(4)菱形查找顺序

  (1)经典类:

    在python2中多继承情况下 在要查找的属性不存在的时候 会执行深度查找

图解:

 

 (3)新式类:

  (1)在python3中如果没有共同的父类 其会执行深度优先

  (2)如果其拥有共同的父类其会执行广度优先

PS:

(1)可以通过mro查看查找顺序

(2)在python2中没有这个参数

 

posted @ 2019-07-25 22:58  SR丶  阅读(263)  评论(0编辑  收藏  举报