前言
写代码时,你是否曾想过把现实世界的事物搬进程序里?比如一只狗会“汪汪”,一只猫会“喵喵”,而它们都属于“动物”。这正是面向对象编程(OOP)的魅力所在。
Python面向对象基础
面向对象的基本概念
Python是一门面向对象的语言(也是一门面向过程的语言)。要掌握面向对象的基本语法,则首先需要掌握两个重要的概念:类、对象。
类: 对现实事物的抽象描述 对象: 现实事物的具体体现
Python类:
# 定义类class 类名: # 定义方法 方法列表...
# 1.定义类class Car: # 2.定义类方法 def run(self): print("能跑起来了...")
对象的基本语法格式 Python对象实例化:
调用方法:
# 定义类class Car: def run(self): print("能跑起来了...")# 创建对象: 对象名 = 类名()car = Car()# 调用行为: 对象名.方法名()car.run()
self关键字 Self是python内置的关键字,用于指向对象实例本身。
class Car: def run(self): print("车跑起来了") def work(self): self.run()car = Car()car.work()
self的常见作用:在类的内部调属性和方法
添加和获取对象属性
属性表示的是固有特征,在Python中使用变量表示,例如人的姓名、年龄、身高、体重等,都是对象的属性。 设置属性
对象名.属性 = 属性值car.color = "黑色"# 定义属性,并给属性color赋值car.number = 10# 给属性number赋值
获取属性值
对象名.属性print("颜色:%s"%car.color)print("轮胎数:%d"%car.number)
class Car: def run(self): print("车跑起来了")car = Car()car.color = '黑色'car.number = 10print(f"车的颜色为:{car.color}")print(f"车的数量为:{car.number}")
类内部获取属性值
class Car: def show(self): # 对象名.属性 = self.属性 print(f"车的颜色为:{self.color}") print(f"车的数量为:{self.number}")car = Car()car.color = '黑色'car.number = 10car.show()
魔法方法
在Python中,有一些可以给Python类增加魔力的特殊方法,它们总是被双下划线所包围,我们称之为魔法方法。 在特殊情况下会被自动调用,不需要开发者手动去调用。
init()方法
自动调用 在Python中,当新创建一个对象时,则会自动触发__init__()魔法方法。 无参数情况:不需要外面传递参数,初始化属性值 有参数情况:当需要外面传递参数,初始化属性值
class Car: # 初始化:无参数,类内部直接赋值 def __init__(self): self.color = 'blue' self.number = 10 def show(self): # 对象名.属性 = self.属性 print(f"车的颜色为:{self.color}") print(f"车的数量为:{self.number}")car = Car()car.show()
class Car: # 初始化:无参数,类内部直接赋值 def __init__(self,color,num): self.color = color self.number = numcar = Car("蓝色",10);print(f"车的颜色:{car.color},车的数量:{car.number}")
str_()方法
自动调用 当使用print输出对象时,默认打印对象的内存地址;如实现了__str__()方法,print就自动调用该魔法方法。
def __str__(self): # ... return 字符串结果
class Car: # 初始化:无参数,类内部直接赋值 def __init__(self,color,num): self.color = color self.number = num def __str__(self): return "车的颜色:"+self.color+",车的数量:"+str(self.number)car = Car("玫瑰色",10);print(car)
del_()方法
当删除对象时(调用del删除对象或文件执行结束后),Python解释器会默认调用__del__()方法。
# 定义类class Car: # 初始化方法:定义品牌类 def __init__(self,brand): self.brand = brand # 定义删除的方法 def __del__(self): print("del 自动调用了__del__()方法")# 创建对象car = Car("BYD")# 获取品牌属性print(car.brand)# 删除对象del car# 获取品牌属性,报错print(car.brand)
Python面向对象高级
定义类的几种语法
方式1:类名
class 类名: 代码 # 定义教师类class Teacher: ...
方式2:类名()
class 类名(): 代码 ...# 定义教师类class Teacher():
方式3:类名(object)
class 类名(object): 代码 ...# 定义教师类class Teacher(object): ....
python中的继承
面向对象代码中的“继承”:指子类继承父类的属性和方法 类是用来描述现实世界中同一组事务的共有特性的抽象模型,但是类也有上下级和范围之分
在Python中,继承形式:
class 父类名(object): ...(省略)class 子类名(父类名): ...(省略)
在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类。
继承:一个类从另一个已有的类获得其成员的相关特性,就叫作继承! (站在子类角度) 派生:从一个已有的类产生一个新的类,称为派生! (站在父类角度) 很显然,继承和派生其实就是从不同的方向来描述的相同的概念而已,本质上是一样的!
父类:也叫作基类,就是指已有被继承的类! 子类:也叫作派生类或扩展类
单继承和多继承
单继承就是一个子类只能继承自一个父类,不能继承多个类。这个子类会有具有父类的属性和方法。 基本语法:
# 父类Fatherclass Father(object): pass# 子类Sonclass Son(Father): pass
多继承就是一个类同时继承了多个父类,并且同时具有所有父类的属性和方法。例如:孩子会继承父亲和母亲的方法和属性 基本语法
# 父类1Fatherclass Father(object): pass# 父类2Motherclass Mother(object): pass# 子类Sonclass Son(Father,Mother): pass
# 1. 师父类,属性和方法class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子')# 为了验证多继承,添加School父类class School(object): def __init__(self): self.kongfu = '[创新煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子')# 2. 定义徒弟类,继承师父类 和 学校类class Prentice(School, Master): pass#3. 用徒弟类创建对象,调用实例属性和方法hgq = Prentice()print(hgq.kongfu)hgq.make_cake()
当一个类有多个父类时,默认使用第一个父类的同名属性和方法,可以使用类名.__mro__属性或类名.mro()方法查看调用的先后顺序。 注:MRO(Method Resolution Order):方法解析顺序
# 通过属性查看引用顺序print(Prentice.__mro__)# 通过方法查看引用顺序print(Prentice.mro())
子类重写父类同名方法和属性
重写也叫作覆盖,就是当子类属性或方法与父类的属性或方法名字相同时,从父类继承下来的成员可以重新定义! 子类重写父类的属性和方法, 优先会调用子类的属性和方法
# 1. 师父类,属性和方法class Master(object): def __init__(self): self.kongfu = '[古法煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子')# 为了验证多继承,添加School父类class School(object): def __init__(self): self.kongfu = '[创新煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子')# 2. 定义徒弟类,继承师父类 和 学校类class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' def make_cake(self): print(f'运用{self.kongfu}制作煎饼果子')hgq = Prentice()print(hgq.kongfu)hgq.make_cake()
如果子类和父类拥有同名属性和方法,子类创建对象调用属性和方法的时候,调用到的是子类里面的同名属性和方法
子类中仍想要保留父类的行为,则需要在子类中调用父类方法.可以直接使用父类名来进行调用,使用的方法:
class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' def make_cake(self): self.__init__() print(f'运用{self.kongfu}制作煎饼果子') def make_school_cake(self): School.__init__(self) # 父类初始化 School.make_cake(self) def make_master_cake(self): Master.__init__(self) # 父类初始化 Master.make_cake(self)hgq = Prentice()hgq.make_cake()hgq.make_master_cake()hgq.make_school_cake()hgq.make_cake()
子类调用父类方法 使用super()调用父类方法,使用的方法:
# 2. 定义徒弟类,继承师父类 和 学校类class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' def make_cake(self): self.__init__() print(f'运用{self.kongfu}制作煎饼果子') def make_old_cake(self): super().__init__() super().make_cake()hgq = Prentice()hgq.make_cake()hgq.make_old_cake()
python中的封装
在软件编程中,将属性和方法书写到类的里面的操作即为封装,封装可以为属性和方法添加私有权限。
私有属性和私有方法
在Python中,可以为属性和⽅法设置私有权限,即设置某个属性或⽅法不继承给⼦类。 设置私有属性和方法的方式:在属性或方法名前面加上 __,格式:
# 私有属性__属性名# 私有方法def __方法名(): ...
私有属性和方法使用规则:
私有属性不能直接访问,在Python中,一般定义方法名’ get_xx ‘用来获取私有属性,定义’ set_xx '用来修改私有属性值。
# 2. 定义徒弟类,继承师父类 和 学校类class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果子配方]' self.__money = 20000 ...... # 得到私有属性__money def get_money(self): return self.__money # 修改私有属性__money def set_money(self,money): self.__money = moneyhgq = Prentice()print(hgq.get_money())hgq.set_money(10000)print(hgq.get_money())
访问私有方法,可以使用重新设置一个公有方法来访问。
# 私有方法 def __make_cake(self): print(f'运用{self.kongfu}制作煎饼果子’) def make(self): self.__make_cake()
python中的多态
多态,指的是:多种状态。比如:同样一个函数在不同的场景下有不同的状态
class Animal: def speak(self): passclass Dog(Animal): def speak(self): print("汪汪汪")class Cat(Animal): def speak(self): print("喵喵喵")def make_noise(animal : Animal): animal.speak()dog = Dog()cat = Cat()make_noise(dog)make_noise(cat)
: Animal 是类型注解(Type Hint),它表示:参数 animal 期望的类型是 Animal 类(或者它的子类)
同样的行为(函数),传入不同的对象,得到不同的状态
实现多态的三个条件 1、有继承 (定义父类、定义子类,子类继承父类) 2、函数重写 (子类重写父类的函数) 3、父类引用指向子类对象 (子类对象传给父类对象调用者)
多态的好处 在不改变框架代码的情况下,通过多态语法轻松的实现模块和模块之间的解耦合;实现了软件系统的可拓展
继承相当于:孩子可以复用老爹的东西。 多态相当于:老爹框架,不做任何修改的情况下,可以可拓展的使用后来人(孩子)写的东西。
抽象类(接口)
父类Animal的speak方法,是空实现
class Animal: def speak(self): pass
在 Python 中,pass 是一个空操作语句,执行时什么也不做。它主要用于语法上需要一条语句、但程序逻辑上不需要任何操作的场合。
这种设计的含义是:
这种写法,就叫做抽象类(也可以称之为接口)
抽象类:含有抽象方法的类称之为抽象类 抽象方法:方法体是空实现的(pass)称之为抽象方法
抽象类就好比定义一个标准,包含了一些抽象的方法,要求子类必须实现
class AC: #制冷 def cool_wind(self): pass # 制热 def hot_wind(self): pass #左右摆风 def swing_l_r(self): passclass Midea_AC(AC): def cool_wind(self): print("美的空调制冷") def hot_wind(self): print("美的空调制热") def swing_l_r(self): print("美的空调左右摆风")class GREE_AC(AC): def cool_wind(self): print("格力空调制冷") def hot_wind(self): print("格力空调制热") def swing_l_r(self): print("格力空调左右摆风")def make_cool(ac : AC): ac.cool_wind()midea = Midea_AC()gree = GREE_AC()make_cool(midea)make_cool(gree)
面向对象的其他属性
属性
类或对象中的属性都属于属性
类属性
类属性,指的就是类所拥有的属性,它被共享于整个类中(即都可以直接调用)。
class Person: count = 10print(Person.count)p = Person()print(p.count)
类方法
所谓类方法,指的是类所拥有的方法,并需要使用装饰器@classmethod来标识其为类方法,同时一定要注意的是对于类方法的第一个参数必须是类对象,通常以cls作为第一个参数名。
@classmethoddef 类方法名(cls): ...类名.类方法名 # 推荐使用对象名.类方法名
class Cat: @classmethod def eat(cls): print("猫都喜欢吃鱼")Cat.eat()c = Cat()c.eat()
静态方法
静态方法需要通过装饰器@staticmethod来标识其为静态方法,且静态方法不需要多定义参数。
@staticmethoddef 静态方法名(): ...类名.静态方法名 # 推荐使用对象名.静态方法名
总结
面向对象不仅仅是语法技巧,更是一种组织复杂程序的思维方式。当你下次再写 Python 代码时,不妨尝试用类来抽象现实逻辑,让代码更贴近自然的认知。实践出真知——快打开你的编辑器,创建一个属于你的 Animal 王国吧!