类与对象
关键字self:指向对象实例本身,像this指针
#简单类的实现
class Phone:
def open(self):
print("手机开机了")
def off(self):
print("手机关机了")
def photo(self):
print("正在拍照中...")
phone = Phone()
phone.open()
phone.photo()
phone.off()魔法方法:
__del__:析构函数
__init__:构造函数
__str__:在输出对象时输出对象信息
class Car:
# color =
# wheel_radius
def __init__(self):#构造
self.color = 'red'
self.wheel_radius = 5
def __str__(self):#输出
return "车的颜色:" + self.color+",车轮半径:" + str(self.wheel_radius)
def __del__(self):#析构
print("the car is deleted!")
def change_wheel_radius(self, new_radius):
if new_radius >= 0:
self.wheel_radius = new_radius
print("wheel_radius changed!")
else:
print("wheel_radius input error!")
def set_color(self, color):
self.color = color
def get_color(self):
return self.color
def run(self):
print("车辆行驶中...")
car = Car()
print(car)
del car
print(car)#报错
# car.color='blue'
# print(f"此时车子的颜色为{car.get_color()}")
# car.run()
# car.change_wheel_radius(-1)
# car.change_wheel_radius(10)
# car.run()继承
"""
小明是个爱学习的好孩子,想学习更多的摊煎饼果子技术,于是,在百度搜索到黑马程序员学校,报班来培训学习摊煎饼果子技术。
"""
class Master(object):
def __init__(self):
self.kongfu="[古法煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Modern(object):
def __init__(self):
self.kongfu="[现代煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Student(Modern,Master):
def __init__(self):
self.kongfu='[独创煎饼果子配方]'
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
self.kongfu='[独创煎饼果子配方]'
def make_modern_cake(self):
Modern.__init__(self)
Modern.make_cake(self)
self.kongfu='[独创煎饼果子配方]'
class Tusun(Student):
pass
John = Student()
John.make_cake()
John.make_master_cake()
John.make_modern_cake()
John.make_cake()
John.make_master_cake()
John.make_cake()
print('\n')
White = Tusun()
White.make_cake()
White.make_master_cake()
White.make_cake()
White.make_modern_cake()
White.make_cake()Python支持多继承,继承方式:class 子类(父类1,父类2...):
如果子类继承了多个父类,那么它会优先使用第一个父类数据
class Master(object):
def __init__(self):
self.kongfu="[古法煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Modern(object):
def __init__(self):
self.kongfu="[现代煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Student(Modern,Master):
pass
xiaoming=Student()
xiaoming.make_cake()
"""
输出结果为:运用[现代煎饼果子配方]制作煎饼果子!
如果顺序为Master先,那么输出结果为:运用[古法煎饼果子配方]制作煎饼果子!
"""重写:子类中写一个和父类一模一样的函数
优先调用子类函数,如果想要使用父类函数就需要在子类内部先调用父类函数
class Master(object):
def __init__(self):
self.kongfu="[古法煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Modern(object):
def __init__(self):
self.kongfu="[现代煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Student(Modern,Master):
def __init__(self):
self.kongfu='[独创煎饼果子配方]'
def make_cake(self):# 在此处的make_cake函数便是重写的体现
print(f"运用了{self.kongfu}制作煎饼果子!")
#此处为在子类中调用父类函数,再通过子类函数发出
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
self.kongfu='[独创煎饼果子配方]'super关键字:可以自动寻找子类的父类,不建议在多继承中使用
class Master(object):
def __init__(self):
self.kongfu="[古法煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Student(Modern,Master):
def __init__(self):
self.kongfu='[独创煎饼果子配方]'
def make_master_cake(self):
super().__init__(self)
super().make_cake(self)
self.kongfu='[古法煎饼果子配方]'
封装
设立私有方法和私有属性使用"__" 双下划线
"""
小明是个爱学习的好孩子,想学习更多的摊煎饼果子技术,于是,在百度搜索到黑马程序员学校,报班来培训学习摊煎饼果子技术。
"""
class Master(object):
def __init__(self):
self.kongfu="[古法煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Modern(object):
def __init__(self):
self.kongfu="[现代煎饼果子配方]"
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
class Student(Modern,Master):
def __init__(self):
self.kongfu='[独创煎饼果子配方]'
self.__money=1000
def get_money(self):
return self.__money
def set_money(self,money):
self.__money=money
def make_cake(self):
print(f"运用了{self.kongfu}制作煎饼果子!")
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
self.kongfu='[独创煎饼果子配方]'
def make_modern_cake(self):
Modern.__init__(self)
Modern.make_cake(self)
self.kongfu='[独创煎饼果子配方]'
class Tusun(Student):
pass
John=Student()
LiMei=Tusun()
print(John.get_money())
print(LiMei.get_money())
# print(LiMei.money)
John.__money=100 #在类外这样直接对私有属性赋值不会生效,钱数不变
# John.set_money(100) #生效
print(John.get_money())内部设立私有方法需要再设置一个公有方法进行访问
多态
class Fighter(object):# 抽象类
def power(self):
pass
class HeroFighter(Fighter):
def power(self):
return 70
class AdvFighter(HeroFighter):
def power(self):
return 80
class EnemyFighter(Fighter):
def power(self):
return 75
def object_play(advfighter:HeroFighter,enemyfighter: EnemyFighter):# 多态实现
if advfighter.power() >enemyfighter.power() :
print('我方战机获胜')
else:
print('敌方战机获胜')
if __name__ == '__main__':
advfighter = AdvFighter()
hero = HeroFighter()
enemy = EnemyFighter()
object_play(hero, enemy)
object_play(advfighter, enemy)
语句解释:
if __name__ == '__main__':
区分该py为模块载入进其他程序还是它作为主程序
如果为主程序载入,那么会从该语句中执行
如果为模块载入其他程序,则不行
抽象类
代码中Fighter类即为抽象类,想象一下,一个类扩散出多个类,可以方便的管理并实现各个子类,这便是抽象类的好处
以下为Kimi给出的抽象类实现代码
print("=" * 60)
print("改进方案:基于抽象类的真正多态设计")
print("=" * 60)
from abc import ABC, abstractmethod
from typing import TypeVar, Generic
# 正确的抽象: Fighter 应该是抽象基类
class Fighter(ABC):
@abstractmethod
def power(self) -> int:
"""返回战斗力"""
pass
@property
@abstractmethod
def name(self) -> str:
"""战机名称"""
pass
# 具体实现
class HeroFighter(Fighter):
@property
def name(self):
return "英雄战机"
def power(self) -> int:
return 70
class AdvFighter(HeroFighter): # 继承 HeroFighter
@property
def name(self):
return "高级战机"
def power(self) -> int:
return 80
class EnemyFighter(Fighter):
@property
def name(self):
return "敌方战机"
def power(self) -> int:
return 75
# 更好的函数设计:接受抽象类型,而非具体类型
def battle(fighter1: Fighter, fighter2: Fighter) -> None:
"""
两个战机对战
Args:
fighter1: 战机1(可以是任何 Fighter 子类)
fighter2: 战机2(可以是任何 Fighter 子类)
"""
print(f"\n⚔️ {fighter1.name} (战力{fighter1.power()}) VS {fighter2.name} (战力{fighter2.power()})")
if fighter1.power() > fighter2.power():
print(f" 🏆 {fighter1.name} 获胜!")
elif fighter1.power() < fighter2.power():
print(f" 🏆 {fighter2.name} 获胜!")
else:
print(" 🤝 平局!")
# 现在可以灵活组合任何战机
hero = HeroFighter()
adv = AdvFighter()
enemy = EnemyFighter()
print("各种对战组合:")
battle(hero, enemy) # 英雄 vs 敌方
battle(adv, enemy) # 高级 vs 敌方
battle(hero, adv) # 英雄 vs 高级(同阵营对战也合理)
battle(enemy, enemy) # 敌方 vs 敌方(内战也合理)属性和方法
没什么好掰扯的,就是讲了两个修饰器
类里面的就称为类属性
# 程序1
class Dog(object):
@classmethod
def eat(cls):
print("小狗都喜欢啃硬骨头...")
Dog.eat() # 类名直接访问
dog = Dog()
dog.eat() # 对象名访问
# 程序2
class Game(object):
@staticmethod
def show_menu():
print("="*20)
print("【1】开始游戏;")
print("【2】暂停;")
print("【0】结束.")
Game.show_menu() # 类名直接访问
game = Game()
game.show_menu() # 对象名访问@classmethod和@staticmethod修饰器
@classmethod意思是该方法为类方法,类方法的第一个参数一定是类对象,通常以cls为参数名
@staticmethod意思是该方法是静态方法,且静态方法不需要定义参数