Python基础知识:面向对象(封装、继承、多态)2
新式类(python3)与旧式类(python2)
领取Python学习资料可以加小编的微信:TZ20200688
多态
案例: 人和普通狗和哮天犬玩耍:
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__
为对象初始化
类也是一个特殊的对象
属性的获取机制
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
定义类属性和类方法
代码:
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
静态方法
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__方法
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)