Python基础知识:面向对象(封装、继承、多态)2

新式类(python3)与旧式类(python2)

领取Python学习资料可以加小编的微信:TZ20200688

Python基础知识:面向对象(封装、继承、多态)2

多态

案例: 人和普通狗和哮天犬玩耍:

class Dog(object):
    def __init__(self, name):
        self.name = name

    def game(self):
        print("%s 蹦蹦跳跳的玩耍..." % self.name)


class XiaoTianQuan(Dog):
    def game(self):
        print("%s 飞到天上玩耍.." % self.name)


class Person(object):
    def __init__(self, name):
        self.name = name

    def play_with_dog(self, dog):
        print("%s 和 %s 一起玩耍..." % (self.name, dog.name))
        dog.game()

p = Person("小明")

dog = Dog("旺财")
p.play_with_dog(dog)

dog = XiaoTianQuan("哮天犬")
p.play_with_dog(dog)

输出:

小明 和 旺财 一起玩耍...

旺财 蹦蹦跳跳的玩耍...

小明 和 哮天犬 一起玩耍...

哮天犬 飞到天上玩耍..

 

类的结构

使用类名()创建对象,创建对象的动作分两步:

  • ①在内存中为对象分配空间;
  • ②调用初始化方法__init__为对象初始化

Python基础知识:面向对象(封装、继承、多态)2

类也是一个特殊的对象

Python基础知识:面向对象(封装、继承、多态)2

属性的获取机制

Python基础知识:面向对象(封装、继承、多态)2

class Tool(object):
    count = 0  # 这个是类属性

    def __init__(self, name):
        self.name = name
        Tool.count += 1  # 统计创建了多少个实例方法


tool1 = Tool("斧头")
tool2 = Tool("榔头")
tool3 = Tool("水桶")
print(Tool.count)  # 3

# 也可以查看对象的count属性 -- > 属性的获取机制
print(tool3.count)  # 3
 

定义类属性和类方法

Python基础知识:面向对象(封装、继承、多态)2

代码:
class Tool(object):

    count = 0

    @classmethod
    def show_tool_count(cls):  # 类方法
        print("工具对象的数量 %d " % cls.count)   # 这个和self类似,取的是类内部的属性和方法

    def __init__(self, name):
        self.name = name
        Tool.count += 1


tool1 = Tool("斧头")
tool2 = Tool("榔头")
tool3 = Tool("扳手")
Tool.show_tool_count()  # 3
 

静态方法

Python基础知识:面向对象(封装、继承、多态)2

 

class Dog(object):

    @staticmethod
    def run():  # 注意这里第一个参数不需要self或者cls
        print("狗在跑...")


# 调用的方式和类方法的方式一样 通过 类名.静态方法 调用静态方法
Dog.run()

三种方法(静态方法、类方法、实例方法)的综合使用(注意: 如果既要访问类属性,又要访问实例属性,就定义实例方法);
class Game(object):
    top_score = 0

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

    @staticmethod
    def show_help():  # 静态方法
        print("游戏帮助信息..")

    @classmethod
    def show_top_score(cls):  # 类方法
        print("目前为止的最高分 %d" % cls.top_score)

    def start_game(self):
        print("%s 开始游戏了..." % self.player_name)


Game.show_help()
Game.show_top_score()
game = Game("小明")
game.start_game()
 

单例模式以及__new__方法

Python基础知识:面向对象(封装、继承、多态)2

class MusicPlayer:
    def __new__(cls, *args, **kwargs):  # 重写父类的__new__方法,必须返回
        print("创建对象,分配空间")
        # 为对象分配空间
        instance = super().__new__(cls)  # 因为__new__方法是一个静态方法,所以要传递cls关键字 (如果是类方法就不需要)
        # 一定要返回,不然就不能分配空间,创建的对象就为None
        return instance

    def __init__(self):
        print("播放器初始化")

player = MusicPlayer()
print(player)

 


输出:

创建对象,分配空间
播放器初始化
<__main__.MusicPlayer object at 0x7f47f2bd09b0>

 


如果只重写__new__方法,没有返回相关的引用,创建的对象就为None。

class MusicPlayer:
    def __new__(cls, *args, **kwargs):  # 重写父类的__new__方法,必须返回
        print("创建对象,分配空间")

    def __init__(self):
        print("播放器初始化")

player = MusicPlayer()
print(player)

输出:

创建对象,分配空间
None

实现单例模式
class MusicPlayer(object):
    instance = None  # 类实例变量
    
    def __new__(cls, *args, **kwargs):  

        if cls.instance is None:
            cls.instance = super().__new__(cls)

        return cls.instance

player1 = MusicPlayer()
player2 = MusicPlayer()
print(player1)  # <__main__.MusicPlayer object at 0x7fd7b631a978>
print(player2)  # <__main__.MusicPlayer object at 0x7fd7b631a978> 和上面的一样

 


上面的单例模式虽然__new__方法只会执行一次,但是__init__还是会执行多次,如何只让初始化只执行一次呢,可以定义一个类变量记录;
class MusicPlayer(object):
    instance = None  # 类实例变量
    init_flag = False

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

        if cls.instance is None:
            cls.instance = super().__new__(cls)

        return cls.instance

    def __init__(self):

        if MusicPlayer.init_flag:  # 已经执行过
            return
        print("初始化播放器")
        MusicPlayer.init_flag = True


player1 = MusicPlayer()
player2 = MusicPlayer()
print(player1)
print(player2)

 

领取Python学习资料可以加小编的微信:TZ20200688