Python面向对象特点的具体实现2(多态、类属性和类方法)

1.多态

复习面向对象的三大特性:

  1. 封装 :根据 职责 将 属性 和 方法 封装 到一个抽象的  中
    • 定义类的准则
  2. 继承 :实现代码的重用,相同的代码不需要重复的编写
    • 设计类的技巧
    • 子类针对自己特有的需求,编写特定的代码
  3. 多态 :不同的 子类对象 调用相同的 父类方法,产生不同的执行结果

    • 多态 可以 增加代码的灵活度
    • 以 继承 和 重写父类方法 为前提
    • 是调用方法的技巧,不会影响到类的内部设计

多态 更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化

2.多态实例

下面的Person和FireMan类具有相同的方法work,但是结果不同,体现出了多态

#定义人类
class Person():
    def __init__(self, name):
        self.name = name
    def work(self):
        print("{0}职员正在进行工作...".format(self.name))
#定义消防员类
class FireMan(Person):
    def work(self):
        print("消防员救火ing...")
#定义火灾类
class Fire():
    def __init__(self, location, degree):
        self.location = location
        self.degree = degree
    def take_place(self):
        print("在{0}发生了一起{1}的火灾".format(self.location, self.degree))
    def put_off(self, fireman):
        fireman.work()
        print("一起发生在{0}的{1}程度的火被消防员{2}扑灭了".format(self.location, self.degree, fireman.name))
#定义主函数
def main():
    fire1 = Fire("A市B街道C号楼", "严重")
    fireman1 = FireMan("dzzhyk")
    common_worker = Person("小明")
    common_worker.work()
    fire1.take_place()
    fire1.put_off(fireman1)
    common_worker.work()
if __name__ == '__main__':
    main()
#输出:
小明职员正在进行工作...
在A市B街道C号楼发生了一起严重的火灾
消防员救火ing...
一起发生在A市B街道C号楼的严重程度的火被消防员dzzhyk扑灭了
小明职员正在进行工作...

3.类属性和类方法

(1)类的结构

1.1 术语 

  1. 使用面相对象开发,第 1 步 是设计 
  2. 使用 类名() 创建对象,创建对象 的动作有两步:
    • 1) 在内存中为对象 分配空间
    • 2) 调用初始化方法 __init__ 为 对象初始化
  3. 对象创建后,内存 中就有了一个对象的 实实在在 的存在 —— 实例

因此,通常也会把:

  1. 创建出来的 对象 叫做  的 实例
  2. 创建对象的 动作 叫做 实例化
  3. 对象的属性 叫做 实例属性
  4. 对象调用的方法 叫做 实例方法

在程序执行时:

  1. 对象各自拥有自己的 实例属性
  2. 调用对象方法,可以通过 self.
    • 访问自己的属性
    • 调用自己的方法

结论

  • 每一个对象 都有自己 独立的内存空间保存各自不同的属性
  • 多个对象的方法在内存中只有一份,在调用方法时,需要把对象的引用 传递到方法内部

1.2 类是一个特殊的对象

Python 中 一切皆对象

  • class AAA: 定义的类属于 类对象
  • obj1 = AAA() 属于 实例对象
  • 在程序运行时, 同样 会被加载到内存
  • 在 Python 中, 是一个特殊的对象 —— 类对象
  • 在程序运行时,类对象 在内存中 只有一份,使用 一个类 可以创建出 很多个对象实例
  • 除了封装 实例 的 属性 和 方法外,类对象 还可以拥有自己的 属性 和 方法
    1. 类属性
    2. 类方法
  • 通过 类名. 的方式可以 访问类的属性 或者 调用类的方法

(2)类属性和实例属性

2.1 概念和使用

  • 类属性 就是给 类对象 中定义的 属性
  • 通常用来记录 与这个类相关 的特征
  • 类属性 不会用于记录 具体对象的特征

示例:top_score是类属性

import random

class Game():
    #类属性-直接在class下使用赋值语句定义
    top_score = 0
    #实例属性-使用__init__定义
    def __init__(self, name):
        self.player_name = name
    #使用@staticmethod创建-类的静态方法
    @staticmethod
    def show_help():
        print("游戏帮助信息")
    #使用@classmethod创建-类方法
    @classmethod
    def show_top_score(cls):
        print(Game.top_score)
    #创建普通的实例方法
    def start_game(self):
        print("开始游戏")
        score = random.random()*100
        if score >= Game.top_score:
            Game.top_score = score
    #创建__del__方法
    def __del__(self):
        print("游戏结束!")
#主程序
time = int(input())
for i in range(time):
    game1 = Game("dzzhyk")
    print("游戏人:{0},第{1}轮游戏".format(game1.player_name, i+1))
    game1.show_help()
    game1.show_top_score()
    game1.start_game()
    print("结束后的最高分为:{0}".format(Game.top_score))


2.2 属性的获取机制

  • 在 Python 中 属性的获取 存在一个 向上查找机制
  • 因此,要访问类属性有两种方式:
    1. 类名.类属性
    2. 对象.类属性 (不推荐)

注意:如果使用 对象.类属性 = 值 赋值语句,只会 给对象添加一个属性而不会影响到 类属性的值

(3)类方法和静态方法

3.1 类方法

  • 类属性 就是针对 类对象 定义的属性
    • 使用 赋值语句 在 class 关键字下方可以定义 类属性
    • 类属性 用于记录 与这个类相关 的特征
  • 类方法 就是针对 类对象 定义的方法
    • 在 类方法 内部可以直接访问 类属性 或者调用其他的 类方法

语法如下

@classmethod
def 类方法名(cls):
    pass
  • 类方法需要用 修饰器 @classmethod 来标识,告诉解释器这是一个类方法
  • 类方法的 第一个参数 应该是 cls
    • 由 哪一个类 调用的方法,方法内的 cls 就是 哪一个类的引用
    • 这个参数和 实例方法 的第一个参数是 self 类似
    • 提示:使用其他名称也可以,不过习惯使用 cls
  • 通过 类名. 调用 类方法调用方法时,不需要传递 cls 参数

在方法内部:

  • 可以通过 cls. 访问类的属性
  • 也可以通过 cls. 调用其他的类方法

3.2 静态方法

  • 在开发时,如果需要在  中封装一个方法,这个方法:

    • 既 不需要 访问 实例属性 或者调用 实例方法
    • 也 不需要 访问 类属性 或者调用 类方法

就可以把这个方法封装成一个 静态方法

@staticmethod
def 静态方法名():
    pass

通过 类名. 调用 静态方法

class Dog(object):
    
    # 狗对象计数
    dog_count = 0
    
    @staticmethod
    def run():
        
        # 不需要访问实例属性也不需要访问类属性的方法
        print("狗在跑...")

    def __init__(self, name):
        self.name = name
        

(4)既需要访问 实例属性 又需要访问 类属性 的情况

如果方法内部 即需要访问 实例属性,又需要访问 类属性,应该定义成 实例方法

因为类只有一个,在 实例方法 内部可以使用 类名. 访问类属性

猜你喜欢

转载自blog.csdn.net/weixin_43826242/article/details/86775450