• Python基础---面向对象2


    事物之间都会存在一些相对应的关系,在面向对象中,类与类之间存在着以下关系:

      依赖关系

      关联,组合,聚合关系,

      实现关系,继承关系

    01.依赖关系:

      将一个类的类名或对象传入到另一个类的方法中

    例1. 设计一个场景:把大象装进冰箱,这个场景中存在两个事物,一个是大象,另一个是冰箱

    class Elephant:
        def __init__(self,name):
            self.name = name
        def open(self,obj):
            print('%s说:开门'%(self.name))
         obj.be_opened()  
    def close(self,obj): print('%s说:关门'%(self.name))
         obj.be_closed()
    class Refrigerator: def __init__(self,name): self.name = name def be_opened(self): print('%s被打开了'%(self.name)) def be_closed(self): print('%s被关闭了'%(self.name)) ele_obj = Elephant('猛犸') haier = Refrigerator('海尔') xinfei = Refrigerator('新飞')
                            # 将冰箱类的实例化对象,传到大象类的方法中
    ele_obj.open(haier)
    ele_obj.close(haier)

    02.组合关系:

      组合:将一个类的对象或类名,封装到另一个类的对象的属性中

    例2. 设计一个场景,男女朋友

    class Boy:
        def __init__(self,name,gf = None):
            self.name = name
            self.gf = gf
        def have_dinner(self):
            if self.gf:
                print('%s和女朋友%s一起共度晚餐'%(self.name,self.gf.name))
            else:
                print('%s自己一个玩'%(self.name))
    class Girl:
        def __init__(self,name):
            self.name = name
    
    
    allen = Boy('allen')
    ruhua = Girl('如花')
    allen.gf = ruhua              # self.gf 拿到的是一个内存地址
    allen.have_dinner()            # allen和女朋友如花一起共进晚餐

    例3. 游戏人物相互攻击

    class GameRole:
        def __init__(self,name,ad,hp):
            self.name = name
            self.ad = ad
            self.hp = hp
        def equipment(self,wea):
            self.wea = wea        # 给人物对象封装一个属性,这个属性是武器类的实例化对象
    class Weapon:
        def __init__(self,name,ad):
            self.name = name
            self.ad = ad
        def wea_attack(self,p1,p2):
            p2.hp -= p1.ad+self.ad
            print('%s用%s攻击了%s,%s掉了%s血,还有%s血'%
                  (p1.name, self.name, p2.name, p2.name,p1.ad+self.ad, p2.hp ))
    # 实例化人物对象
    yasuo
    = GameRole('亚索',20,200) mumu = GameRole('木木',10,200) # 实例化武器对象 sword = Weapon('太刀',10) hammer = Weapon('锤子',10) # 给人物封装武器属性 yasuo.wea = sword mumu.wea = hammer yasuo.wea.wea_attack(yasuo,mumu) mumu.wea.wea_attack(mumu.attack)

    03.继承关系:

     3.1.单继承

      3.1.1通过类名或对象执行父类方法:

    class Animal:
        type_name = '动物类'    
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def eat(self):
            print('in Animal eat')
    class Person(Animal):
        pass
    1.执行父类方法
    # 类名调用:
    print(Person.eat(123))
    print(Person.type_name)
    # 对象调用:
    obj = Person('小一',18,'')
    obj.eat()                # in Animal eat
    obj.type_name = '123'
    print(obj.__dict__)                # {'name':'小一','age':18,'sex':男,'type_name':'123'}

    执行步骤:

      (1)实例化对象obj,执行__init__方法,子类空间没有,就去父类空间找,父类空间如果没有,就继续往上找(python3中的父类默认为object)

      (2)obj.eat(),先执行子类空间中的eat方法,没有就去父类空间中找

      3.1.2同时执行子类和父类的方法:

    class Animal:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def func(self):
            print('in Animal func')
    class Person(Animal):
        def func():
            Animal.func(self)        # 类名.方法名时,必须要传参
            super().func()           # super方法,func()中不用传参数
            print('in Person func') 
    p1 = Person('小一',18)
    p1.func()                in Animal func  in Person func

      3.1.3同时执行子类和父类的__init__方法:

    class Animal:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    class Person(Animal):
        def __init__(self,name,age,sex):
            Animal.__init__(self,name,age)
            super().__init__(name,age)
            self.sex = sex
    p1 = Person('小一',18,'')
    print(p1.__dict__)            {'name':'小一','age':18,'sex':'男'}

      3.1.4 super( )方法:

        完全按照对象所在类的mro顺序执行,在多继承中,super(指定类名,self).方法名(),super中指定的类会被跳过,执行mro的下一个顺序的类的方法

    class A:
        def func1(self):
            print('in A func1')
    class B(A):
        def func1(self):
            super(B, self).func1()        跳过B,执行C
            print('in B func1')
    class C(A):
        def func1(self):
           print('in C func1')
    class D(B,C):
        def func1(self):
            super(D, self).func1()       跳过D,执行B
            print('in D func1')
    obj = D()
    obj.func1()
    print(D.mro())                    继承顺序:D.B.C.A

     3.2多继承

      3.2.1 python中类的分类: 经典类,新式类

        py2x版本中: py2.2之前只有经典类,不继承object类,遵循的是深度优先原则,从左至右一条路走到黑

        py2.2之后,出现新式类,继承object类,遵循C3算法,mro顺序

        py3x版本中: 所有的类都默认继承object类

      3.2.2 经典类的多继承:

        深度优先原则,从左至右一条路走到黑

       mro顺序: Foo --> H --> G --> F --> E --> D --> B --> A --> C

      3.2.3 新式类的多继承: 当两个父类出现了重名的方法时,遵循C3算法,mro顺序

      (1)mro序列: 是一个有序的列表,在类被创建时就会计算出来

        通用公式为:mro(Child(Base1,Base2)) = [Child] + merge(mro(Base1),mro(Base2),[Base1,Base2])

      (2)继承至一个基类: classB(A)

    mro(B) = mro(B(A)) = [B] + merge(mro(A),[A]) = [B] + merge([A]+[A]) = [B,A]

      (3)继承至多个基类: classB(A1,A2,A3...)

    mro(B) = merge(B(A1,A2,A3...))
    = [B] + merge(mro(A1),mro(A2),mro(A2)...[A1,A2,A3...]) 
    = ...

      (4)表头和表尾: 

        表头: 列表的第一个元素

        表尾: 除第一个元素外其他元素

    如计算merge( [E,O], [C,E,F,O], [C] )
                  1        2       3
    01.merge不为空,取出第一个列表列表1的表头E,进行判断                              
       各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
    02.取出列表2的表头C,进行判断
       C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
    
    merge( [E,O], [C,E,F,O], [C] ) = [C] + merge( [E,O], [E,F,O])
    03.进行下一次新的merge操作 ......    

    例:

    mro(A) = mro(A(B,C))
           = [A] + merge(mro(B),mro[C],[B,C])
    mro(B) = mro(B(D,E))
           = [B] + merge(mro(D),mro(E),[D,E])
           = [B] + merge([D,O],[E,O],[D,E])
           = [B] + [D] + merge([O],[E,O],[E])
           = [B,D,E] + merge([O]) = [B,D,E,O]
    mro(C) = mro(C(E,F)) = [C,E,F,O]
    mro(A) = [A] + merge([B,D,E,O] + [C,E,F,O] + [B,C])
        = [A,B] + merge([D,E,O] + [C,E,F,O] + [C])
        = [A,B,D] + merge([E,O] + [C,E,F,O] + [C])
        = [A,B,D,C] + merge([E,O] + [E,F,O])
        = [A,B,D,C,E] + merge([O] + [F,O])
        = [A,B,D,C,E,F,O]

    4.面向对象的三大特性:封装,继承,多态

      封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式。

    优点:便于使用,提高复用性和安全性

      继承:可以使子类具有父类的各种属性和方法,而且不需要再次编写相同的代码,在子类继承父类的同时,可以重新定义某些属性,重写某些方法,即覆盖父类中原有的属性和方法,使子类具有不同于父类的功能,此外,给子类追加新的属性和方法也是很常见的做法.

    继承的优点: 增强代码的耦合性,减少重复代码,使代码更加规范化,合理化

      多态:指一类事物有多种形态.python默认支持多态,一个变量可以是多种数据类型

       鸭子类型: 如果看起来是鸭子,那它就是鸭子,两个类虽没有任何关系,但隐形中遵循了一个标准

       优点:1.统一标准,减少了词汇量,建立了一种弱关联;2.两个类没有任何的耦合性,但是可以产生关系,A的对象会使用B类的方法

  • 相关阅读:
    js导出table到excel,同时兼容FF和IE
    Android 程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短信
    [置顶] 让金融互联网-P2P网贷融资量增长10倍的广告宣传公益活动
    Headroom.js插件用法
    HDU 5289 Assignment(单调队列)
    sh_Spring整合Hibernate
    怎样高速启动Android模拟器(Android Emulator)
    设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)
    在c++11中你最惊讶的新feature是什么?
    python的私有化
  • 原文地址:https://www.cnblogs.com/py8318/p/10345473.html
Copyright © 2020-2023  润新知