面向对象(三)

面向对象编程

多继承

所谓多继承,即子类有多个父类,并且具有它们的特征。

image.png
class Father(object):
    def run(self):
        print("Father会跑")


class Father1(object):
    def run(self):
        print("Father1会跑")


class Son(Father, Father1):
    pass


s = Son()
s.run()          # Father会跑 左边优先
image.png
class GrandFather(object):
    def sleep(self):
        print("GrandFather 睡觉")


class Father(GrandFather):
    def run(self):
        print("Father 会跑")


class Father1(object):
    def run(self):
        print("Father1会跑")

    def sleep(self):
        print('Father1 睡觉')


class Son(Father, Father1):
    pass


s = Son()
s.sleep()           # GrandFather 睡觉  左边一条路走到底
image.png
class GrandFather(object):
    def sleep(self):
        print("GrandFather 睡觉")


class Father(GrandFather):
    def run(self):
        print('Father 会跑')


class Father1(GrandFather):
    def run(self):
        print("Father1 会跑")

    def sleep(self):
        print("Father1 睡觉")


class Son(Father, Father1):
    pass


s = Son()
s.sleep()       # Father1 睡觉  同一个根时,根最后执行
print(Son.__mro__)      # C3算法
"""
python支持多继承
- 1.左边优先
- 2.一条道路走到底
- 3.同一个根时,根最后执行
"""

多态

多态的概念是应用于 Java 和 C# 这一类强类型语言中,而 Python 崇尚"鸭子类
型"
动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要
“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态。

class Person(object):
    def print_self(self):
        print('自我介绍')


class Man(Person):
    def print_self(self):
        print('man的自我介绍')


def print_self(obj):
    obj.print_self()


zs = Person()
# zs.print_self()
print_self(zs)

hansen = Man()
# hansen.print_self()
print_self(hansen)

面向对象编程

魔法方法介绍

在Python中,有一些内置好的特定方法,这些方法在进行特定的操作时会自动被调
用,称为魔法方法。
魔法方法的命名总是被4120双下划线包围,比如__ 名称 __

常用魔法方法

__doc__:用来查看类的说明文档
练习:
查看列表类的说明文档

 print(list().__doc__)

 li = list('abc')
 print(li.__doc__)

s = '1234'
print(s.__doc__)

class Demo(object):
    """
    我是注释
    """
    pass


d = Demo()
print(d.__doc__)
print(Demo.__module__)  # __main__ 指的是当前文件所在的模块
print(Demo.__class__)   # Demo类是type的对象 <class 'type'>
print(d.__class__)      # d是Demo对象

常用魔法方法

__dict__ :用于获取类或者实例的属性字典
注意:

  • 实例属性存储在对象中,所以通过 对象 .__dict__ 获取的是实例属性
  • 除实例属性以外的成员都存储在类中,所以通过 类 .__dict__来获取
class Demo(object):
    country = '中国'

    def __init__(self):
        self.name = 'deng'
        self.__age = 18

    def test(self):
        self.gender = 'female'
        print('test')


d = Demo()
d.test()
print(d.__dict__)       # 字典,对象去访问,只能访问到对象中的成员(实例属性)
print(Demo.__dict__)    # 字典,类名去访问,就可以访问到类当中的成员(除了实例属性之外的属性与方法)

print(d.__dir__())      # 列表,返回所有的成员(__dict__更倾向于 是__dir__()的子集)

常用魔法方法

__del__():叫做析构方法。当由该类创建的实例对象,被删除或者说在内存中被释
放,将会自动触发执行。
总结:

  • 当代码全部执行完毕才自动触发__del__()
  • 如果需要提前触发,则需要通过 del关键字,删除所有对象后触发 __del__()
    注意:
    此方法一般不需要定义,因为 Python 是一门高级语言,程序员在使用时无需关心
    内存的分配与释放,一般都是交给 Python 解释器来执行。所以,析构函数的调用
    是由解释器在进行垃圾回收时自动触发执行。
class Demo(object):
    def __del__(self):
        print('我被回收了')


d = Demo()      # 1
print('--'*10)
print('--'*10)
                # 2 在所有代码都执行完毕之后,会自动执行 __del__方法

class Demo(object):
    def __del__(self):
        print('我被回收了')


d = Demo()          # 1
print('--'*10)      # 2
del d               # 3 通过关键字 del 将对象删除则会主动的执行__del__方法
print('--'*10)      # 4


class Demo(object):
    def __del__(self):
        print('我被回收了')
        
        
d = Demo()      # 1
d1 = d
print('--'*10)  # 2
del d
del d1          # 3
print('--'*10)  # 4 只有当对象全部释放 才会自动触发__del__

"""
注意:python解释器会有自动的垃圾回收机制,所以,我们并不需要主动的去封装__del__()
"""

常用魔法方法

call() :用于将对象变成一个可调用的对象。也就是说,当一个类中有
call() 方法时,其实例化得到的对象便是可调用的 (callable)

class Demo(object):
    def __init__(self):
        print('aaa')

    def __call__(self, *args, **kwargs):
        print('我可以调用了奥')


d = Demo()
d()         # Demo()() TypeError: 'Demo' object is not callable

常用魔法方法

new() :用于创建与返回一个对象。在类准备将自身实例化时调用。

练习:
所示右边代码打印输出的顺序?
A.init,new
B.init
C.new
D.__new,init

image.png
class Dome(object):
    def __init__(self):
        print('__init__')

    def __new__(cls, *args, **kwargs):
        # 重写了父类的new方法,对象并没有创建成功,所以不会再触发__init__方法
        print('__new__')


d = Dome()
# 1.__init__创建对象之后自动调用的方法
# 2.__new__用来创建对象的

class A(object):
    def sleep(self):
        print('创建对象')


class B(A):
    def sleep(self):
        print('我在玩')


d = B()
d.sleep()       # 我在玩

常用魔法方法

对象创建执行顺序

    1. 通过__new__()方法 创建对象
    1. 并将 对象返回,传给__init__()
      练习:
      在自定义类中实现创建对象
      思路:
  • 重写父类__new__()方法
  • 并且在该方法内部,调用父类的__new__() 方法
class Dmeo(object):
    def __init__(self):
        print('__init__')

    def __new__(cls, *args, **kwargs):
        print('__new__')

        # 重写父类的__new__,还需要执行父类的代码
        # super().__new__(cls)      # 执行了父类创建对象的代码,还并没有自动的执行__init__
        return super().__new__(cls) # 将对象返回出去,自动执行__init__方法


d = Dmeo()
# __new__
# __init__

注意

  • 在创建对象时,一定要将对象返回,才会自动触发__init__() 方法
  • __init__()方法当中的 self ,实际上就是 __new__返回的实例,也就是该对象
    __init__()__new__() 区别:
  • __init__实例方法, __new__静态方法
  • __init__ 在对象创建后自动调用,__new__ 创建对象的方法

单例模式介绍

单例模式是一种常用的软件设计模式。也就是说该类只包含一个实例。
通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而
方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在
一个,单例模式是最好的解决方案。
通常应用在一些资源管理器中,比如日志记录等。

class Single(object):
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)


s = Single()
s1 = Single()
print(id(s))        # 25891376
print(id(s1))       # 25892176
'''
当对象不存在的时候-->创建对象
当对象已经存在的时候-->永远只返回当前对象
'''

class Single(object):
    __isinstance = None     # 1.类属性,建立标识

    def __new__(cls, *args, **kwargs):
        if cls.__isinstance is None:
            cls.__isinstance = super().__new__(cls)     # 2.将一个对象存储到__isinstance类属性中。

            # 3.返回cls.__isinstance,也就是我们的对象
            return cls.__isinstance
        else:
            # 4.__isinstance不为None,意味着它已经储存着一个对象,我们直接将放回出去即可
            return cls.__isinstance


s = Single()
s1 = Single()
s2 = Single()
print(id(s))        # 23730128
print(id(s1))       # 23730128
print(id(s2))       # 23730128

思路

  • 当对象不存在时,创建对象
  • 当对象存在时,永远返回当前已经创建对象
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • day10.面向对象三【Python教程】 一、练习:设计类 1. 设计一个卖车的4S店,该怎样做呢? 说明 上面...
    Java帮帮阅读 661评论 1 2
  • 一.类属性和实例属性 class Person(object): country ='china'#类属性 d...
    无敌帅帅头阅读 287评论 0 0
  • 面向对象主要包含,类和对象。类就是一类对象抽象出来的,是具有相同属性和行为事物的统称。我们的类主要分为:类名、属...
    rookieyu阅读 490评论 0 1
  • 面向对象 创建类 通过class关键字定义,类名最好以大写字母开头,举例: 实例化 直接调用类即可实例化,举例: ...
    dawsonenjoy阅读 524评论 0 1
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 5,706评论 0 5