类与对象

关键字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意思是该方法是静态方法,且静态方法不需要定义参数