Python基础--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类实例化一个对象raux = Refrigerator("奥克斯")   # Refrigerator类实例化一个对象auxr.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): # 子类
    passclass Dog(Animal):  # 子类
    passclass Cat(Animal):  # 子类
    passclass 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): # 子类
    passclass 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): # 子类
    passclass 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 = hobbyclass 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):
    passf = 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):
    passclass C(E,F):
    name = "金刚"class A(B,C):
    passa = 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 进行
目录
相关文章
|
2月前
|
Java 程序员 C++
Python 面向对象详解!
本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。
77 2
|
16天前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
33 4
|
2月前
|
Python
Python面向对象(2)
【10月更文挑战第14天】
Python面向对象(2)
|
2月前
|
设计模式 程序员 C语言
Python面向对象
【10月更文挑战第13天】
Python面向对象
|
1月前
|
弹性计算 Linux iOS开发
Python 虚拟环境全解:轻松管理项目依赖
本文详细介绍了 Python 虚拟环境的概念、创建和使用方法,包括 `virtualenv` 和 `venv` 的使用,以及最佳实践和注意事项。通过虚拟环境,你可以轻松管理不同项目的依赖关系,避免版本冲突,提升开发效率。
71 3
|
2月前
|
索引 Python
python-类属性操作
【10月更文挑战第11天】 python类属性操作列举
23 1
|
2月前
|
Java C++ Python
Python基础---类
【10月更文挑战第10天】Python类的定义
26 2
|
2月前
|
设计模式 开发者 Python
Python类里引用其他类
Python类里引用其他类
28 4
|
2月前
|
设计模式 开发者 Python
Python 类中引用其他类的实现详解
Python 类中引用其他类的实现详解
46 1
|
2月前
|
JSON 缓存 API
在 Python 中使用公共类处理接口请求的响应结果
在 Python 中使用公共类处理接口请求的响应结果
36 1