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

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中类的继承关系使用什么符号_Python 入门 之 类的三大关系(依赖 / 组合/ 继承关系)...相关推荐

  1. python在长字符串中寻找重复子串_Python 入门到精通

    1.变量 1.python不用事先声明变量,赋值过程中就包含了变量声明和定义的过程 2.用"="赋值,左边是变量名,右边是变量的值 1.1. 数字 整数 int_var = 1 长 ...

  2. python类中数据成员_Python 入门 之 类成员

    1.类的私有成员 私有: 只能自己拥有 以 __ 开头就是私有内容 对于每一个类的成员而言都有两种形式: - 公有成员,在任何地方都能访问 - 私有成员,只有在类的内部才能使用 私有成员和公有成员的访 ...

  3. 深度学习入门基于Python的理论与实现_第一章_Python入门(原创笔记)

    前言 此书使用Python作为编程语言,尽可能地少使用外部库,从零开始实现深度学习的程序. 此书从简单的机器学习问题开始,最终实现一个能高精度地识别图像的系统. 此书以图像识别为主题,主要学习使用深度 ...

  4. python强制用什么作为语句缩进符号_python从入门到放弃 第二天 谈谈python代码中的冒号和缩进...

    如同格子衬衫一样规整的源代码书写层次,是一个优秀的码农必备的编程习惯.python的作者无意就是这样一个人. python是用冒号(:)和强制缩进作为代码层次来划分代码组的.这是一个很小的知识点,但是 ...

  5. python中类方法可以访问实例属性吗_Python类方法访问属性

    Python类方法访问属性教程 Python 中的 Python实例方法访问属性详解 语法 class People: money = 10000 def __init__(self, name): ...

  6. python中定义字典数据类型使用什么符号_python数据类型之字典类型-dict

    1.dict-基本使用 1.用途:用来存多个值,单每一个值都有一个key与之对应, key对值有描述性的功能,存储多个值表示的不同不同状态 2.定义:{}内用逗号分隔开多个元素,每一个元素都是key: ...

  7. python语言的特点有没有面向过程_Python 入门基础之面向对象过程-面向过程概述...

    首先说明一下,python既是面向过程的语言,也是面向对象的语言,所以说python很灵活. 一句话简单说一下什么叫做面向对象编程OOP(object-oriented programing):面向对 ...

  8. python中修饰器的优点和作用_Python入门基础教程之装饰器

    Python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  9. python在子类中添加新的属性_python - 如何创建类属性?

    python - 如何创建类属性? 在python中,我可以使用@classmethod装饰器向类添加方法. 是否有类似的装饰器向类中添加属性? 我可以更好地展示我在说什么. class Exampl ...

最新文章

  1. [Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明
  2. cxGRID能否对模板进行保存
  3. JavaScript基础总结
  4. 机床使用教学_2020沧州cnc培训20年教学经验颁发职业
  5. A Mini Locomotive POJ - 1976(动态规划+思维)
  6. 点集的视点特征直方图的评估
  7. webpack vs gulp 一张图说明
  8. js页面滚动时层智能浮动定位实现(jQuery/MooTools)
  9. java迭代器怎么用_Java中迭代器的使用
  10. Atitit.linq java的原理与实现 解释器模式
  11. 优控触摸屏使用手册_中达优控PLC触摸屏一体机说明书.pdf
  12. 如何部署服务器虚拟化,vmware服务器虚拟化方案(vmware虚拟化平台部署)
  13. MATLAB人脸识别算法
  14. 图像匹配滤波器 matlab,[转载]匹配滤波器的仿真验证(MATLAB)
  15. 什么是ANC降噪技术?耳机工厂来告诉你
  16. html按钮点击后无效,关于html中按钮的单击事件,第一次单击可以运行,再次单击不能运行的解决方法...
  17. setResult(RESULT_OK, intent)回调不执行问题
  18. Windows10 LTSB/LTSC 企业版安装应用商店
  19. 企业与个人必备安全测试工具
  20. android平板打电话,打电话上网不耽误,通话平板你需要吗?

热门文章

  1. 天津和塘沽两天一夜自由行(第二天)
  2. windows seven小技巧
  3. 大神驾到 | 游戏UI赏析之—全面战争:三国
  4. 【阿里聚安全·安全周刊】阿里安全潘多拉实验室完美越狱iOS11.2.1|Janus漏洞修改安卓app而不影响签名
  5. 对接爱快递快递API接口
  6. 关于matlab表情包,基于matlab人脸表情识别
  7. 以大数据眼光欣赏唐人文墨(二)代码实现
  8. React 实际开发中一些要点—立哥技术
  9. IBM Security Guardium V10的新增功能
  10. 常用CSS与Jquery选择器