• Python——面向对象基础(上):析构、继承、类and实例属性和方法、多态(day08)


    目录

    一、析构方法

    二、单继承

    三、多继承

    四、间接继承

    五、重写(方法覆盖)和调用父类方法

    六、类属性和实例属性

    七、类方法和静态方法 

    八、多态


    在python中展现面向对象的三大特征:
    封装、继承、多态
    封装:指的是把内容封装到某个地方,便于后面的使用
    他需要:
    把内容封装到某个地方
    从另外一个地方去调用被封装的内容
    对于封装来说 其实就是使用初始化构造方法将内容封装到对象中,然后通过对象直接或者self来获取被封装的内容

    继承: 和现实生活当中的继承是一样的:也就是 子可以继承父的内容【属性和行为】(爸爸有的儿子都有,相反 儿子有的爸爸不一定有)
     所以对于面向对象的继承来说  其实就是将多个类共有的方法提取到父类中 子类仅需继承父类而不必一一去实现
     这样就可以极大的提高效率 减少代码的重复编写,精简代码的层级结构 便于拓展

     class 类名(父类):
          '''
           子类就可以继承父类中公共的属性和方法
          '''
         pass


    为什么要使用静态方法呢
    # 由于静态方法主要来存放逻辑性的代码,本身和类以及实例对象没有交互,
    # 也就是说,在静态方法中,不会涉及到类中方法和属性的操作
    # 数据资源能够得到有效的充分利用

    从方法定义的形式可以看出来
    1.类方法的第一个参数是类对象 cls 进而去引用类对象的属性和方法  必须用装饰器 @classmethod来修饰
    2.实例方法的第一个参数必须是self,通过这个self 可以去引用类属性或者实例属性,若存在相同名称实例属性和类属性的话,实例属性的优先级最高
    3.静态方法不需要定义额外的参数,若是要引用属性的话 则可以通过类对象或者是实例对象去引用即可   必须用装饰器 @staticmethod来修饰

    多态:顾名思义就是多种状态、形态,就是同一种行为 对于不同的子类【对象】有不同的行为表现

    要想实现多态 必须的有两个前提需要遵守:
    1、继承:多态必须发生在父类和子类之间
    2、重写: 子类重写父类的方法

    多态有什么用:
    增加程序的灵活性
    增加程序的拓展性

    一、析构方法

     

    1. class Animal:
    2. def __init__(self,name):
    3. self.name=name
    4. print('这是构造初始化方法')
    5. pass
    6. def __del__(self):
    7. # 主要的应用就是来操作 对象的释放 一旦释放完毕 对象便不能在使用
    8. print('当在某个作用域下面 没有被使用【引用】的情况下 解析器会自动的调用此函数 来释放内存空间')
    9. print('这是析构方法')
    10. print('%s 这个对象 被彻底清理了 内存空间也释放了'%self.name)
    11. pass
    12. cat=Animal('小花猫')
    13. # del cat #手动的去清理删除对象 会指定__del__函数
    14. print(cat.name)
    15. input('程序等待中.....')
    16. # print('*'*40)
    17. # dog=Animal('柯基小狗')

    没写del方法,程序自己也会有,程序运行结束后自动调用并释放内存

    二、单继承

    1. class Animal:
    2. def eat(self):
    3. '''
    4. :return:
    5. '''
    6. print('吃饭了')
    7. pass
    8. def drink(self):
    9. '''
    10. :return:
    11. '''
    12. pass
    13. class Dog(Animal): #继承了Animal 父类 此时dog就是子类
    14. def wwj(self):
    15. '''
    16. 子类独有的实现
    17. :return:
    18. '''
    19. print('小狗汪汪叫')
    20. pass
    21. class Cat(Animal):
    22. def mmj(self):
    23. '''
    24. 子类独有的实现
    25. :return:
    26. '''
    27. print('小猫喵喵叫')
    28. pass
    29. d1=Dog()
    30. d1.eat() #具备了吃的行为 是继承了父类的行为
    31. d1.wwj()
    32. print('**************cat 的行为**********************')
    33. c1=Cat()
    34. c1.eat()
    35. c1.mmj()

    三、多继承

    可以将类C继承别的类方法不变,如果是广度优先则会输出类C中的方法也就是C.eat.深度优先的会就会输出类D的方法即D.eat.结果是D.eat.所以是深度优先

    这里遵从的虽然是广度优先,不是深度优先,但是输出C还是因为类C将类D中的eat方法重写了导致类B继承D类的eat方法变成了C.eat

    1. class shenxian:
    2. def fly(self):
    3. print("神仙都会飞")
    4. pass
    5. class Monkey:
    6. def chitao(self):
    7. print('猴子喜欢吃桃')
    8. pass
    9. class Sunwukong(shenxian,Monkey): #即使神仙 同时也是猴子
    10. pass
    11. # swk=Sunwukong()
    12. # swk.chitao()
    13. # swk.fly()
    14. # 问题是 当多个父类当中存在相同方法的时候 应该去调用哪一个呢
    15. class D(object):
    16. def eat(self):
    17. print('D.eat')
    18. pass
    19. pass
    20. class C(D):
    21. def eat(self):
    22. print('C.eat')
    23. pass
    24. pass
    25. class B(D):
    26. pass
    27. class A(B,C):
    28. pass
    29. a=A()
    30. a.eat()
    31. print(A.__mro__) #可以显示类的依次继承关系
    32. #在执行eat的方法时 查找方法的顺序是
    33. # 首先到A里面去查找 如果A中没有 则继续的去B类中去查找 如果B中没有
    34. # 则去C中查找 如果C类中没有 则去D类中去查找,如果还是没有找到 就会报错
    35. # A-B-C-D 也是继承的顺序

    四、间接继承

    1. class GrandFather:
    2. def eat(self):
    3. print('吃的 方法')
    4. pass
    5. pass
    6. class Father(GrandFather):
    7. def eat(self): #因为父类中已经存在这个的方法 在这里相当于 方法重写【方法覆盖了】
    8. print('爸爸经常吃海鲜')
    9. pass
    10. class Son(Father):
    11. pass
    12. son=Son()
    13. print(Son.__mro__)
    14. son.eat() #此方法 是从GrandFather继承过来的

    一般不超多三级传递。

    五、重写(方法覆盖)和调用父类方法

    1. # 所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
    2. # 为什么要重写, 父类的方法已经不满足子类的需要,那么子类就可以重写父类或者完善父类的方法
    3. class Dog:
    4. def __init__(self,name,color):
    5. self.name=name
    6. self.color=color
    7. def bark(self):
    8. print('汪汪叫....')
    9. pass
    10. pass
    11. class kejiquan(Dog):
    12. def __init__(self,name,color):#属于重写父类的方法
    13. # 针对这种需求 我们就需要去调用父类的函数了
    14. # Dog.__init__(self,name,color) #手动调用 调用父类的方法了 执行完毕就可以具备name,color这两个实例属性了\
    15. super().__init__(name,color) #super是自动找到父类 进而调用方法, 假设继承了多个父类,那么会按照顺序逐个去找 然后在调用
    16. # 这样写还可以拓展其他的属性,如下
    17. self.height=90
    18. self.weight=20
    19. pass
    20. def __str__(self):
    21. return '{}的颜色会{} 它的身高是{}cm 体重是:{}'.format(self.name,self.color,self.height,self.weight
    22. )
    23. def bark(self): #属于重写类的方法
    24. super().bark() #调用父类的方法
    25. print('叫的跟神一样')
    26. print(self.name)
    27. pass
    28. kj=kejiquan('柯基犬','红色')
    29. kj.bark()
    30. print(kj)

    六、类属性和实例属性

    1. # 属性:类属性和实例属性
    2. # 类属性 就是类对象所拥有的属性
    3. class Student:
    4. name='李明' #属于类属性 就是student类对象所拥有的
    5. def __init__(self,age):
    6. self.age=age #实例属性
    7. pass
    8. @staticmethod
    9. def aaa(x,y):
    10. print(x+y)
    11. pass
    12. Student.name='李易峰' #通过类对象去修改数据 可以修改的 因为name的所拥有的权利属于类对象
    13. lm=Student(18)
    14. print(lm.name) #通过实例对象去访问类属性
    15. # lm.name='刘德华' #通过实例对象 对类属性进行修改 可以吗? 不可以的,只是增加一个实例属性,不能修改类属性
    16. print(lm.name)
    17. print(lm.age)
    18. Student.aaa(4,6)
    19. print('---------xh的数据---------------')
    20. xh=Student(28)
    21. print(xh.name)
    22. print(xh.age)
    23. print('---------通过类对象 student 去访问name---------------')
    24. # print(Student.name) 如 类名.属性名 形式去访问
    25. # print(Student.age)
    26. # 小结
    27. # 类属性是可以 被类对象和实例对象共同访问使用的
    28. # 实例属性只能由实例对象所访问

    调用时,现在自己这个实例对象中找,没有再去上一级类中去找,类对象中也没有时会报错

    通过 :类名.属性名 的形式也可以访问类属性

    七、类方法和静态方法 

    (1)类方法

     (2)静态方法

     声明静态方法后,就没必要通过实例对象调用了,即使可以这样调用

    # 为什么要使用静态方法呢
    # 由于静态方法主要来存放逻辑性的代码,本身和类以及实例对象没有交互,
    # 也就是说,在静态方法中,不会涉及到类中方法和属性的操作
    # 数据资源能够得到有效的充分利用
    1. class People:
    2. country='china'
    3. #类方法 用 classmethod 来进行修饰
    4. @classmethod
    5. def get_country(cls):
    6. return cls.country #访问类属性
    7. pass
    8. @classmethod
    9. def change_country(cls,data):
    10. cls.country=data #修改类属性的值 在类方法中
    11. pass
    12. @staticmethod
    13. def getData():
    14. return People.country #通过类对象去引用
    15. pass
    16. @staticmethod
    17. def add(x,y):
    18. return x+y
    19. pass
    20. print(People.add(10,56)) #带有参数的静态方法
    21. # print(People.getData())
    22. # print(People.get_country()) #通过类对象去引用
    23. p=People()
    24. print(p.getData()) #注意 一般情况下 我们不会通过实例对象去访问静态方法
    25. # print('实例对象访问 %s'%p.get_country())
    26. # print('-----------------修改之后---------------------------')
    27. # People.change_country('英国')
    28. # print(People.get_country()) #通过类对象去引用
    29. # 为什么要使用静态方法呢
    30. # 由于静态方法主要来存放逻辑性的代码,本身和类以及实例对象没有交互,
    31. # 也就是说,在静态方法中,不会涉及到类中方法和属性的操作
    32. # 数据资源能够得到有效的充分利用
    33. # demo 返回当前的系统时间
    34. import time # 引入第三方的时间模块
    35. class TimeTest:
    36. def __init__(self,hour,min,second):
    37. self.hour=hour
    38. self.min = min
    39. self.second = second
    40. @staticmethod
    41. def showTime():
    42. return time.strftime("%H:%M:%S",time.localtime())
    43. pass
    44. pass
    45. print(TimeTest.showTime())
    46. t=TimeTest(2,10,15)
    47. print(t.showTime()) #没有必要通过这种方式去访问 静态方法

    八、多态

    1. # 案例演示
    2. class Animal:
    3. '''
    4. 父类【基类】
    5. '''
    6. def say_who(self):
    7. pri# 案例演示
    8. class Animal:
    9. '''
    10. 父类【基类】
    11. '''
    12. def say_who(self):
    13. print('我是一个动物....')
    14. pass
    15. pass
    16. class Duck(Animal):
    17. '''
    18. 鸭子类 【子类】 派生类
    19. '''
    20. def say_who(self):
    21. '''
    22. 在这里重写父类的方法
    23. :return:
    24. '''
    25. print('我是一只漂亮的鸭子')
    26. pass
    27. pass
    28. class Dog(Animal):
    29. '''
    30. 小狗类 【子类】 派生类
    31. '''
    32. def say_who(self):
    33. print('我是一只哈巴狗')
    34. pass
    35. pass
    36. class Cat(Animal):
    37. '''
    38. 小猫类 【子类】 派生类
    39. '''
    40. def say_who(self):
    41. print('我是一只小花猫 喵喵喵喵')
    42. pass
    43. pass
    44. class Bird(Animal):
    45. '''
    46. 新增鸟类 无需修改原来的代码
    47. '''
    48. def say_who(self):
    49. print('我是一只黄鹂鸟')
    50. pass
    51. class People:
    52. def say_who(self):
    53. print('我是人类')
    54. pass
    55. class student(People):
    56. def say_who(self):
    57. print('我是一年级的学习 张明')
    58. pass
    59. def commonInvoke(obj):
    60. '''
    61. 统一调用的方法
    62. :param obj: 对象的实例
    63. :return:
    64. '''
    65. obj.say_who()
    66. # duck1=Duck()
    67. # duck1.say_who()
    68. # dog1=Dog()
    69. # dog1.say_who()
    70. # cat1=Cat()
    71. # cat1.say_who()
    72. listObj=[Duck(), Dog(),Cat(),Bird(),student()]
    73. for item in listObj:
    74. '''
    75. 循环去调用函数
    76. '''
    77. commonInvoke(item)
    78. nt('我是一个动物....')
    79. pass
    80. pass
    81. class Duck(Animal):
    82. '''
    83. 鸭子类 【子类】 派生类
    84. '''
    85. def say_who(self):
    86. '''
    87. 在这里重写父类的方法
    88. :return:
    89. '''
    90. print('我是一只漂亮的鸭子')
    91. pass
    92. pass
    93. class Dog(Animal):
    94. '''
    95. 小狗类 【子类】 派生类
    96. '''
    97. def say_who(self):
    98. print('我是一只哈巴狗')
    99. pass
    100. pass
    101. class Cat(Animal):
    102. '''
    103. 小猫类 【子类】 派生类
    104. '''
    105. def say_who(self):
    106. print('我是一只小花猫 喵喵喵喵')
    107. pass
    108. pass
    109. class Bird(Animal):
    110. '''
    111. 新增鸟类 无需修改原来的代码
    112. '''
    113. def say_who(self):
    114. print('我是一只黄鹂鸟')
    115. pass
    116. class People:
    117. def say_who(self):
    118. print('我是人类')
    119. pass
    120. class student(People):
    121. def say_who(self):
    122. print('我是一年级的学习 张明')
    123. pass
    124. def commonInvoke(obj):
    125. '''
    126. 统一调用的方法
    127. :param obj: 对象的实例
    128. :return:
    129. '''
    130. obj.say_who()
    131. # duck1=Duck()
    132. # duck1.say_who()
    133. # dog1=Dog()
    134. # dog1.say_who()
    135. # cat1=Cat()
    136. # cat1.say_who()
    137. listObj=[Duck(), Dog(),Cat(),Bird(),student()]
    138. for item in listObj:
    139. '''
    140. 循环去调用函数
    141. '''
    142. commonInvoke(item)

  • 相关阅读:
    网络安全-黑客攻击
    计算机408看不懂?那是你还不知道这套学习方法和资源
    【编程题】【Scratch二级】2022.03 跳跃游戏
    移动端抓包
    SQL面试题练习 —— 用户行为路径分析
    高仿英雄联盟游戏网页制作作业 英雄联盟LOL游戏HTML网页设计模板 简单学生网页设计 静态HTML CSS网站制作成品
    【Azure API 管理】解决API Management添加AAD Group时遇见的 Failed to query Azure Active Directory graph due to error 错误
    Android LinearLayout快速设置每个item间隔
    docker启动链接sqlservr的镜像时报SSl错误
    MIPI CSI-2笔记(16) -- 数据格式(YUV图像数据)
  • 原文地址:https://blog.csdn.net/qq_47941078/article/details/125370412