class Person: def __init__(self,name,weight): # self.属性 = 形参 self.name = name self.weight = weight def __str__(self): return "我的名字是%s 体重是%.2f 公斤" % (self.name,self.weight) def run(self): print("%s 爱跑步 , 跑步锻炼身体" % self.name) self.weight -= 0.5 def eat(self): print("%s 爱吃饭 , 吃饭增长体重" % self.name) self.weight += 1 xiaoming = Person("小明",75.0) xiaoming.run() xiaoming.eat() print(xiaoming) xiaomei = Person("小美",45.0) xiaomei.run() xiaomei.eat() print(xiaomei) # 多个对象之间互不影响 小明 爱跑步 , 跑步锻炼身体 小明 爱吃饭 , 吃饭增长体重 我的名字是小明 体重是75.50 公斤 小美 爱跑步 , 跑步锻炼身体 小美 爱吃饭 , 吃饭增长体重 我的名字是小美 体重是45.50 公斤
家具类:家具类简单,房子要使用到家具,在开发中被使用的类先开发
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s 占地 %.2f" % (self.name, self.area) bed = HouseItem("席梦思", 4) chest = HouseItem("衣柜", 2) table = HouseItem("餐桌", 1.5) print(bed) print(chest) print(table) 席梦思 占地 4.00 衣柜 占地 2.00 餐桌 占地 1.50
定义房子类
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s 占地 %.2f" % (self.name, self.area) class House: def __init__(self, house_type, area): self.house_type = house_type self.area = area self.free_area = area self.item_list = [] def __str__(self): return ("户型:%s\\n总面积: %.2f\\n剩余面积:%.2f\\n家具: %s" % (self.house_type, self.area, self.free_area, self.item_list)) # python能自动将括号里的代码连接到一起 def add_item(self,item): print("要添加%s" % item) bed = HouseItem("席梦思", 4) chest = HouseItem("衣柜", 2) table = HouseItem("餐桌", 1.5) print(bed) print(chest) print(table) my_house = House("两室一厅", 60) my_house.add_item(bed) my_house.add_item(chest) my_house.add_item(table) 席梦思 占地 4.00 衣柜 占地 2.00 餐桌 占地 1.50 要添加席梦思 占地 4.00 要添加衣柜 占地 2.00 要添加餐桌 占地 1.50
完成摆放家具:
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "%s 占地 %.2f" % (self.name, self.area) class House: def __init__(self, house_type, area): self.house_type = house_type self.area = area self.free_area = area self.item_list = [] def __str__(self): return ("户型:%s\\n总面积: %.2f\\n剩余面积:%.2f\\n家具: %s" % (self.house_type, self.area, self.free_area, self.item_list)) # python能自动将括号里的代码连接到一起 def add_item(self,item): print("要添加%s" % item) if item.area > self.free_area: print("%s面积太大" % item.area) return self.item_list.append(item.name) self.free_area -= item.area bed = HouseItem("席梦思", 4) chest = HouseItem("衣柜", 2) table = HouseItem("餐桌", 1.5) print(bed) print(chest) print(table) my_house = House("两室一厅", 60) my_house.add_item(bed) my_house.add_item(chest) my_house.add_item(table) print(my_house) 席梦思 占地 4.00 衣柜 占地 2.00 餐桌 占地 1.50 要添加席梦思 占地 4.00 要添加衣柜 占地 2.00 要添加餐桌 占地 1.50 户型:两室一厅 总面积: 60.00 剩余面积:52.50 家具: ['席梦思', '衣柜', '餐桌']
一个对象的属性可以是另一个类创建的对象
枪类:
class Gun: def __init__(self, model): self.model = model self.bullet_count = 0 def add_bullet(self, count): self.bullet_count += count def shoot(self): if self.bullet_count <= 0: print("%s没有子弹了" % self.model) return self.bullet_count -= 1 print("%s突突突%d" % (self.model, self.bullet_count)) ak47 = Gun("ak47") ak47.add_bullet(50) ak47.shoot() ak47突突突49
士兵类:
class Gun: def __init__(self, model): self.model = model self.bullet_count = 0 def add_bullet(self, count): self.bullet_count += count def shoot(self): if self.bullet_count <= 0: print("%s没有子弹了" % self.model) return self.bullet_count -= 1 print("%s突突突%d" % (self.model, self.bullet_count)) class Soldier: def __init__(self, name): self.name = name self.gun = None def fire(self): if self.gun == None: print("%s还没有枪" % self.name) return print("冲啊...%s" % self.name) self.gun.add_bullet(50) self.gun.shoot() ak47 = Gun("ak47") xusanduo = Soldier("许三多") xusanduo.gun = ak47 xusanduo.fire() 冲啊...许三多 ak47突突突49
用于比较两个对象的内存地址是否相同—是否为对同一个对象的引用
应用场景
定义方式
class Women: def __init__(self, name): self.name = name self.__age = 18 def secret(self): # 在对象的方法内部可以访问私有属性 print("%s的年龄是%d" % (self.name, self.__age)) xiaofan = Women("小芳") # print(xiaofan.age) xiaofan.secert() 小芳的年龄是18
python中不存在真正的私有属性和私有方法
class Women: def __init__(self, name): self.name = name self.__age = 18 def secret(self): # 在对象的方法内部可以访问私有属性 print("%s的年龄是%d" % (self.name, self.__age)) xiaofan = Women("小芳") print(xiaofan._Women__age) xiaofan.secret()
面向对象三大特性:
class Animal: def eat(self): print("吃") **class dog(Animal):**# 继承 def bark(self): print("叫") dog = dog() dog.bark() dog.eat()
术语: 子类,父类,继承
派生类,基类,派生
继承的传递性
父类的方法不能满足子类的需求,就需要子类对方法进行重写
class Animal: def eat(self): print("吃") class dog(Animal):# 继承 def bark(self): print("叫") def eat(self): print("吃骨头") super().eat() dog = dog() dog.bark() dog.eat() 叫 吃骨头 吃
概念:子类可以拥有多个父类,拥有所有父类的属性和方法
语法:class 子类名(父类名1,父类名2)
当前类→父类1→父类2→object类
object是python为所有对象提供的基类,提供一些内置方法和属性,可以使用dir方法函数查看
class A(object): pass class B: pass a = A() b = B() print(dir(a)) print(dir(b)) # 新版本python中默认为新式类 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
特性:不同子类对象调用相同的方法,产生不同执行结果
需求
class Dog(): 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(): def __init__(self, name): self.name = name def game_with_dog(self, dog): print("%s和%s快乐的玩耍" % (self.name, dog.name)) dog.game() wangcai = Dog("旺财") huahua = xiaotianquan("飞天花花") xiaoming = person("小明") xiaoming.game_with_dog(wangcai) xiaoming.game_with_dog(huahua) 小明和旺财快乐的玩耍 旺财蹦蹦跳跳的玩耍 小明和飞天花花快乐的玩耍 飞天花花飞到天上去玩
- class AAA:定义的类属于类对象
- obj1 = AAA()属于实例对象
概念:
示例需求:
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
属性获取机制(了解):
在python中获取属性存在向上查找机制
class Tool(object): count = 0 def __init__(self,name): self.name = name Tool.count +=1 tool1 = Tool("斧头") tool2 = Tool("榔头") tool3 = Tool("水桶") print(tool3.count) # 不建议使用,因为会给对象添加count属性 3
@classmethod def 类方法名(cls): pass
实力需求:
class Tool(object): count = 0 @classmethod def show_tool_count(cls): print("工具对象的数量 %d" % cls.count) def __init__(self,name): self.name = name Tool.count +=1 tool1 = Tool("斧头") tool2 = Tool("榔头") tool3 = Tool("水桶") Tool.show_tool_count() 工具对象的数量 3
- 在开发中,需要封装一个方法:
- 不需要访问实例属性或者实例方法
- 也不需要访问类属性和类方法
- 这个时候可以封装成静态方法
- 通过 类名. 调用
- 语法
@staticmethod def 静态方法名(): pass简单的示例:
class Dog(object): @staticmethod def run(): 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() 帮助信息: 历史记录0 小明开始游戏啦
设计模式:
单例设计模式:
**new 方法:**
class MusicPlayer(object): def __new__(cls, *args, **kwargs): print("创建对象,分配空间") return super().__new__(cls) def __init__(self): print("播放器初始化") player1 = MusicPlayer() player2 = MusicPlayer() print(player1) print(player2) 创建对象,分配空间 播放器初始化 创建对象,分配空间 播放器初始化 <__main__.MusicPlayer object at 0x0000028CFCFB3E50> <__main__.MusicPlayer object at 0x0000028CFCFB3E20>
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) print(player2) <__main__.MusicPlayer object at 0x0000024C8E613EE0> <__main__.MusicPlayer object at 0x0000024C8E613EE0>
扩展:
每次创建对象时,python会自动调用两个方法:
创建对象时还会调用初始化方法
需求:让初始化方法只执行一次
解决方法:
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) 初始化播放器 <__main__.MusicPlayer object at 0x0000022EE6713E80> <__main__.MusicPlayer object at 0x0000022EE6713E80>