+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-08(106)

2019-09(105)

2019-10(7)

2019-11(8)

2019-12(13)

2020-01(23)

2020-02(22)

Python 入门 之 类的三大关系(依赖 / 组合/ 继承关系)

发布于2020-01-01 12:24     阅读(405)     评论(0)     点赞(13)     收藏(1)


Python 入门 之 类的三大关系(依赖 / 组合/ 继承关系)

在面向对象的中,类与类之间存在三种关系:依赖关系、组合关系、继承关系。

1、依赖关系:将一个类的类名或对象当做参数传递给另一个函数被使用的关系就是依赖关系

class People:

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

    def open(self,bx):
        bx.open_door(self)

    def close(self,bx):
        bx.close_door(self)


class Refrigerator:

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

    def open_door(self,p):
        print(f"{p.name} 打开冰箱")

    def close_door(self,p):
        print(f"{p.name} 关闭冰箱")


r = People("大魔")   # People类实例化一个对象r
aux = Refrigerator("奥克斯")   # Refrigerator类实例化一个对象aux
r.open(aux)    # 将aux对象当做参数传递给r对象的open方法使用
r.close(aux)   # 将aux对象当做参数传递给r对象的close方法使用

2、组合关系:将一个类的对象封装到另一个类的对象的属性中,就叫组合

class Boy:

    def __init__(self,name,g):
        self.name = name    # self = b
        self.g = g         # g就是girl类实例化的一个对象内存地址

    def eat(self):
        print(f"{self.name}{self.g.age}岁,且{self.g.weight}公斤的{self.g.name}py朋友.一起吃了个烛光晚餐!")

    def make_keep(self):
        self.g.live(f"{self.g.weight}公斤的{self.g.name}{self.name}踩背")


class Girl:

    def __init__(self,name,age,sex,weight,*args):
        self.name = name
        self.age = age
        self.sex = sex
        self.weight = weight
        self.args = args

    def live(self,argv):
        print(f"直播内容:{argv}")


g = Girl("乔毕得",54,"女",220)
b = Boy("太博",g)    # 将对象g当做属性封装到b对象的属性中
b.make_keep()

3、继承关系

(1)什么是面向对象的继承

​ 继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。
​ 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。

(2)程序中 A(B)

<1> A -- 子类,派生类

<2> B -- 父类,基类,超类

当我们写多个类的时候会发现许多问题如:

class Human:

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

    def eat(self):
        print("吃")

class Dog:

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

    def eat(self):
        print("吃")

class Cat:

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

    def eat(self):
        print("吃")

class Pig:

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

    def eat(self):
        print("吃")

上述代码重复,这时我们可以简化相关代码如:

class Animal: # 父类
    """
    动物类
    """
    live = "活的"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self 是函数的位置参数
        print("吃")

class Human(Animal): # 子类
    pass

class Dog(Animal):  # 子类
    pass

class Cat(Animal):  # 子类
    pass

class Pig(Animal):  # 子类
    pass

(3)继承的优点:

<1> 减少重复代码

<2> 结构清晰,规范

<3> 增加耦合性(耦合性不宜多,在精)

(4)继承的分类:

<1> 单继承

<2> 多继承

Python2: python2.2 之前都是经典类,python2.2之后出现了新式类,继承object就是新式类
Python3: 只有新式类,不管你继不继承object都是新式类

(5)单继承:

<1> 通过子类的类名使用父类的属性和方法

class Animal: # 父类

    live = "活的"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self 是函数的位置参数
        print("吃")

class Human(Animal): # 子类
    pass

class Dog(Animal):  # 子类
    pass
    
Human.eat(12)
Human.__init__(Human,"大魔",18,"男")

print(Human.live)
print(Human.__dict__)

<2> 通过子类的对象使用父类的属性和方法

class Animal: # 父类

    live = "活的"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self 是函数的位置参数
        print("吃")

class Human(Animal): # 子类
    pass

class Dog(Animal):  # 子类
    pass
    
p = Human("大魔",18,"男")
d = Dog("remmom",1,'母')
print(d.__dict__)
print(p.__dict__)

p = Human("大魔",18,"男")
print(p.live)

(6)查找顺序:

<1> 不可逆(就近原则)

<2> 通过子类,类名使用父类的属性或方法(查找顺序):当前类,当前类的父类,当前类的父类的父类---->

<3> 通过子类对象使用父类的属性或者方法(查找顺序):先找对象,实例化这个对象的类,当前类的父类--->

(7)同时使用子类和父类方法或属性:

<1> 方法一:不依赖(不需要)继承

class Animal: # 父类

    live = "活的"

    def __init__(self, name, age, sex):
        # self = p的内存地址
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self 是函数的位置参数
        print("吃")

class Human: # 子类

    def __init__(self, name, age, sex, hobby):
        # print(Animal.live)
        # self = p的内存地址
        Animal.__init__(self,name,age,sex)  # 直接使用Animal类调用Animal类中的方法
        self.hobby = hobby

class Dog:

    def __init__(self, name, age, sex, attitude):
        # self = p的内存地址
        self.name = name
        self.sex = sex
        self.age = age
        self.attitude = attitude      # 与Human类进行比较


p = Human("大魔",18,"男","健身")
print(p.__dict__)

<2> 方法二:依赖(需要)继承

class Animal: # 父类

    live = "活的"

    def __init__(self, name, age, sex):
        # self = p的内存地址
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self 是函数的位置参数
        print("吃")
        
   class Dog(Animal):

    def __init__(self, name, age, sex, attitude):
        # self = p的内存地址
        # super(Dog,self).__init__(name,age,sex)   # 完整写法
        super().__init__(name,age,sex)   # 正常写法  # 通过super方法使用父类中的方法
        self.attitude = attitude

d = Dog("大魔",18,"男","忠诚")
print(d.__dict__)

习题练习:

class Base:
    def __init__(self, num):   
        self.num = num

    def func1(self):
        print(self.num)
        self.func2()

    def func2(self):
        print("Base.func2")

class Foo(Base):
    def func2(self):
        print("Foo.func2")

obj = Foo(123)
obj.func1()
class Base:
    def __init__(self, num):
        self.num = num

    def func1(self):
        print(self.num)
        self.func2()

    def func2(self):
        print(111, self.num)

class Foo(Base):
    def func2(self):
        print(222, self.num)

lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
    obj.func1()

(8)多继承

多继承是继承多个父类

​ 多继承中, 存在着这样⼀个问题. 当两个⽗类中出现了重名⽅法的时候. 就会涉及到如何查找⽗类⽅法的这么⼀个问题.即MRO(method resolution order) 问题. 在python中这是⼀个很复杂的问题. 因为在不同的python版本中使⽤的是不同的算法来完成MRO的.

(1)经典类:多继承时从左向右执行

class A:
    name = "小宝"

class B(A):
    name = "太博"

class C(A):
    name = "marry"

class D(B, C):
    name = "魔22"

class E:
    name = "魔11"

class F(E):
    name = "魔"

class G(F, D):
    name = "bb"
    
class H:
    name = "aaa"

class Foo(H, G):
    pass

f = Foo()
print(f.name)

#  结果为aaa

总结:

经典类:(深度优先)左侧优先,一条路走到头,找不到会回到起点向右查询

(2)新式类:采用c3算法 (也有说用广度优先的 -- 不精确)

# 下述例子在python2.7中运行
class O(object):
    name = "小宝"

class D(O):
    name = "天魔"

class E(O):
    name = "太博"

class F(O):
    name = "marry"

class B(D,E):
    pass

class C(E,F):
    name = "金刚"

class A(B,C):
    pass

a = A()
print a.name

#  结果为     天魔

(3)c3 算法的核心 mro

<1> mro() -- python提供的可以查看多继承时的执行顺序的一种方法
<2> MRO是一个有序列表L,在类被创建时就计算出来。通用计算公式为:
mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
(其中Child继承自Base1, Base2)
如果继承至一个基类:class B(A) 这时B的mro序列为
mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]
如果继承至多个基类:class B(A1, A2, A3 …) 这时B的mro序列
mro(B) = mro( B(A1, A2, A3 …) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...
计算结果为列表,列表中至少有一个元素即类自己,如上述示例[A1,A2,A3]。merge操作是C3算法的核心。
<3> 表头和表尾
表头:   列表的第一个元素
表尾:   列表中表头以外的元素集合(可以为空)

示例   列表:[A, B, C]   表头是A,表尾是B和C

<4> 列表之间的+操作

+操作:

[A] + [B] = [A, B] (以下的计算中默认省略) ---------------------

merge操作示例:

如计算merge( [E,O], [C,E,F,O], [C] )
有三个列表 :  ①        ②      ③

1 merge不为空,取出第一个列表列表①的表头E,进行判断                              
   各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
2 取出列表②的表头C,进行判断
   C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
   merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3 进行下一次新的merge操作 ......
---------------------
<5> 经典类不能使用mro , 新式类才能使用mro


所属网站分类: 技术文章 > python文章

作者:短发越来越短

链接: http://www.pythonheidong.com/blog/article/197496/

来源:python黑洞网 www.pythonheidong.com

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

13 0

赞一赞 or 踩一踩

收藏该文
已收藏

评论内容:(最多支持255个字符)

相似文章

  re学习笔记(42)安恒杯二月月赛-re- easy-py

  用Python3解决LeetCode买卖股票的最佳时机

  《Opencv计算机视觉实战》笔记_1:图像操作

  记录python之pyecharts安装

  使用python列表的pop方法求解约瑟夫环问题

  03.分支结构

  Python数据结构与算法(1)——引入

  【Django 003】创建多个应用拆分项目.

  python经典练习题十道(六)

  Numpy 的常用操作

优质资源排行榜

 python经典电子书大合集下载 下载次数 8139

 零基础java开发工程师视频教程全套,基础+进阶+项目实战(152G) 下载次数 7550

 零基础前端开发工程师视频教程全套,基础+进阶+项目实战(共120G) 下载次数 7442

 零基础大数据全套视频400G 下载次数 7006

 零基础php开发工程师视频教程全套,基础+进阶+项目实战(80G) 下载次数 6893

 零基础软件测试全套系统教程 下载次数 6506

 全套人工智能视频+pdf 下载次数 6443

 IOS全套视频教程 基础班+就业班 下载次数 4680

 编程小白的第一本python入门书(高清版)PDF下载 下载次数 3654

10  effective python编写高质量Python代码的59个有效方法 pdf下载 下载次数 3366

11  Python深度学习 pdf下载 下载次数 3156

12  笨办法学python pdf下载 下载次数 3088

13  Python Cookbook第三版中文PDF下载高清完整扫描原版 下载次数 3025

14  树莓派Python编程指南 pdf下载 下载次数 3011

15  python从入门到精通视频(全60集)python视频教程下载 下载次数 3009

16  python项目开发视频 下载次数 3002

17  使用python+pygame开发的小游戏《嗷大喵快跑》源码下载 下载次数 3000

18  黑马2017年java就业班全套视频教程 下载次数 2992

19  Python基础教程 pdf下载 下载次数 2988

20  python实战项目 平铺图像板系统源码下载,适用于想要保存,标记和共享图像,视频和网页的用户 下载次数 2987

21  利用python实现程序内存监控脚本 下载次数 2987

22  老男孩python自动化视频 下载次数 2983

23  老王python基础+进阶+项目视频教程 下载次数 2974

24  尚硅谷Go学科全套视频 下载次数 2972

25  某硅谷Python项目+AI课程+核心基础视频教程 下载次数 2968

26  Web前端实战精品课程 下载次数 2967

27  Python算法教程_中文版 pdf下载 下载次数 2967

28  tron python小游戏 下载次数 2963

29  [小甲鱼]零基础入门学习Python 下载次数 2962

30  老男孩python全栈开发15期 下载次数 2958

31  2017最新web前端开发完整视频教程附源码 下载次数 2948

32  最新全套完整JAVAWEB2018开发视频 下载次数 2926

33  流畅的Python PDF下载高清完整扫描原版 下载次数 2922

34  Spring boot实战视频6套下载 下载次数 2910

35  Python高性能编程 pdf下载 下载次数 2908

36  python全套视频十五期(116G) 下载次数 2908

37  Python项目实战 下载次数 2887

38  利用Python进行数据分析 pdf下载 下载次数 2885

39  30个小时搞定Python网络爬虫 含源码 下载次数 2884

40  简明python教程 (A Byte of Python)pdf下载 下载次数 2884

41  python全自动抢火车票教程-python视频教程下载 下载次数 2883

42  尚硅谷大数据之Hadoop视频 下载次数 2876

43  Python A~B~C~ python视频教程下载 下载次数 2866

44  数据结构与算法视频(小甲鱼讲解-全) 下载次数 2864

45  web小程序表白天数倒计时源码下载 下载次数 2863

46  python基础视频教程 下载次数 2862

47  go语言全套视频 下载次数 2855

48  清华学霸尹成Python爬虫视频-ok 下载次数 2846

49  黑马前端36期最全视频和代码 下载次数 2843

50  2018最新全套web前端视频教程+源码下载 下载次数 2842