• [7天通关Python基础]-13:面向对象的三大特征:封装、继承和多态


    在这里插入图片描述

    一、了解什么是类

    1.定义一个简单的类

    在Python中,类通过 class 关键字定义,类名通用习惯为首字母大写,Python3中类基本都会继承于object类,语法格式如下,我们创建一个Circle圆类:

    class Circle(object):  # 创建Circle类,Circle为类名
       pass  # 此处可添加属性和方法
    
    • 1
    • 2

    注意: 我们定义的类都会继承于object类,当然也可以不继承object类;两者区别不大,但没有继承于object类使用多继承时可能会出现问题。

    有了Circle类的定义,就可以创建出具体的circle1、circle2等实例,circle1和circle2是个实际的圆。创建实例使用 类名+(),类似函数调用的形式创建。

    如下我们创建两个Circle类的实例:

    circle1= Circle()
    circle2= Circle()
    
    • 1
    • 2

    创建好实例对象后,我们就可以使用类中定义的所有方法。

    2.self变量

    哪个对象调用方法或者属性,self就是那个值

    # python定义类,类名可以不加括号,默认继承object类
    class Human:
        def eat(self):
            print('人吃饭', id(self))
    
        def sleep(self):
            print('人要睡觉', id(self))
    
    if __name__ == '__main__':
    	zs = Human()
    	zs.eat()
    	zs.sleep()
    	print(id(zs))
    	
    	ls = Human()
    	ls.eat()
    	ls.sleep()
    	print(id(ls))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    3.类属性和实例属性

    class People:
        father = '张三'
    
        def fun(self, mother):
            return '爸爸是{},妈妈是{}'.format(self.father, mother)
    
    if __name__ == '__main__':
        people = People()
        print(people.fun('丽丽'))
        print(id(people.father))  # 类属性可以通过对象名.变量名
        print(id(People.father))  # 也可以用类名.变量名
    
        people.father = '李四'  # 实例属性只修改自己的值,与原来的值无关,类似一个局部变量
        People.father = '王五'  # 会修改整个类的值,但是有的对象通过对象名.变量修改过值的,无法再修改,因为此时地址已经不同
        print(people.father)
        print(People.father)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述


    二、面向对象的三大特征

    1.封装

    • 定义: 封装是将类中的某些方法或者属性隐藏,对象不能直接使用隐藏的方法或者属性,具有保护功能
    • 格式: __属性(方法),使用双下划线
    • 目的: 保护隐私
    • 如何调用: 只有在本类的内部可以使用,外部不可以修改和使用

    举例:

    class Girl:
        name = '张三'
        __age = 15
    
        def show(self):
            print(self.name, self.__age)
    
    
    if __name__ == '__main__':
        g = Girl()
        g.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    我们输出age

    print(g.age)
    # 或者
    print(g.__age)
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    因为是私有属性,外部不可直接使用

    g = Girl()
    g.__age = '20'
    print(g.__age)
    
    • 1
    • 2
    • 3

    这样使用并不是修改类中的__age,而是重新创建了一个__age的属性

    另外我们可以使用实例对象.__dict__方法查看所有a属性的元素

    print(g.__dict__)#---{'name': '张三', '_Girl__age': 10, '__age': 15}
    
    • 1

    但是如果非想改,可以使用实例对象._类名__属性名修改,但是不建议使用

    比如修改:

    g = Girl()
    g._Girl__age = 30
    g.show()
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    2.继承

    • 定义: 子类需要使用父类的属性和方法,但是子类中也可以定义自己的属性和方法。
    • 概念: 被继承的类叫父类/基类/超类,继承的类叫子类/派生类

    2.1 单继承

    class Animal:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print('吃')
    
        def sleep(self):
            print('睡')
    
    class Cat(Animal):#-------------------继承谁就在括号里写谁
        def jiao(self):
            print('喵')
    
    class Dog(Animal):
        def jiao(self):
            print('汪')
    
    if __name__ == '__main__':
    	c = Cat('猫', 10)
    	d = Dog('狗', 12)
    	c.eat()#-----------------吃
    	d.eat()#-----------------吃
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    查看父类的方法__bases__

    print(Cat.__bases__)#(<class '__main__.Animal'>,)
    print(Animal.__bases__)#(<class 'object'>,),object是所有类的组宗,这种类叫新式类
    
    • 1
    • 2

    2.2 方法重写

    当子类要使用的方法在父类中已经定义,但是和自己想用的方法有出入,那么就可以对父类的方法进行重写

    class A():
        def hehe(self):
            print('呵呵')
    class B(A):
        def hehe(self):
            print('哈哈')
    
    if __name__ == '__main__':
    	a=A()
    	b=B()
    	a.hehe() #呵呵
    	b.hehe() #哈哈
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.3 super方法

    子类和父类有相同的方法,如果子类下个调用父类相同的方法可以使用super

    class Animal():
        def __init__(self,name):
            self.name=name
    class Cat(Animal):
        def __init__(self,name,speed):
            self.speed=speed
            super().__init__(name)
        def jiao(self):
            print(self.name,self.speed)
    
    if __name__ == '__main__':
    	c=Cat('波斯猫',3500)
    	c.jiao() 
    
    # 结果:波斯猫  3500
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.4 多继承

    多继承如果父类们拥有共同的方法则按照第一个顺序进行继承

    class A:
        def shuchu(self):
            print('A')
    
    
    class B():
        def shuchu(self):
            print('B')
    
    
    class C(A, B):
        def shuchu3(self):
            print('C')
    
    
    if __name__ == '__main__':
        c = C()
        c.shuchu()  
    
    # 结果:A
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.5 多继承的本质

    提示:mro方法可以根据广度优先算法,得出继承顺序,一步一步执行

    class A():
        def func(self):
            print('A开始')
            print('A结束')
    
    class B(A):
        def func(self):
            print('B开始')
            super().func()
            print('B结束')
    class C(A):
        def func(self):
            print('C开始')
            super().func()
            print('C结束')
    class D(B,C):
        def func(self):
            print('D开始')
            super().func()
            print('D结束')
    d=D()
    d.func()
    
    class A:
        def __init__(self):
            print('A开始')
            print('A结束')
    class B(A):
        def __init__(self):
            print('B开始')
            super().__init__()
            print('B结束')
    class C(A):
        def __init__(self):
            print('C开始')
            super().__init__()
            print('C结束')
    class D(B,C):
        def __init__(self):
            print('D开始')
            super().__init__()
            print('D结束')
    # d=D()
    print(D.mro())
    # 按此mro列表中的从左到右开始查找积累,直到找到第一个匹配的属性的类为止
    # 也就是多个父类,按照此列表的顺序被检查
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在这里插入图片描述
    此类题不用init方法,用别的方法也是一样

    2.6 关于继承的一些注意事项

    1. 子类继承父类,如果子类不重写父类的某个方法,那么子类执行父类的方法
    2. 子类继承父类,如果子类复写了某个方法,那么子类只使用自己的方法
    3. 父类的私有属性不能被继承

    3.多态

    python是弱类型语言,python中处处是多态;python中没有多态,但是有鸭子类型 ()一些类含有相同的方法,则这些类就互称为鸭子

    class Alipay():
        def pay(self):
            print('支付宝支付')
    
    
    class Wechatpay():
        def pay(self):
            print('微信支付')
    
    
    class Person():
        def xiaofei(self, a):
            a.pay()
    
    
    if __name__ == '__main__':
        ali = Alipay()
        wx = Wechatpay()
        p = Person()
        p.xiaofei(wx)
        p.xiaofei(ali)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

  • 相关阅读:
    专为云原生、微服务架构而设计的链路追踪工具 【SkyWalking介绍及搭建】
    (附源码)springboot苔藓植物科普网站 毕业设计 345641
    .Net 6 WebAPI 使用JWT进行 授权认证配置
    【Spring传播机制底层原理】
    电容笔和Apple pencil区别有什么?双十一值得入手的电容笔推荐
    1.DesignForSetting\1.AutoCreateMatchGroup
    什么是正向代理和反向代理
    问题 - 谷歌浏览器 network 看不到接口请求解决方案
    开源数据库 SQLite 发布 3.37.0 版本
    51单片机-第三节-LCD1602调试工具,矩阵键盘
  • 原文地址:https://blog.csdn.net/qq_40558166/article/details/125562687