面向对象编程 OOP:(Object-Oriented Programming)是一种将数据和相关操作封装在一起的编程方式 类:对一系列具有相同特征和行为的食物的统称(一个抽象概念,不是真实存在的事务) 对象:由类创建出来的真实存在的事务 特征即属性, 行为即方法 ▶ 类(Class):类是对象的蓝图或模板,定义了对象的属性和方法 ▶ 对象(Object):类的实例化结果,根据类创建的具体实体 ▶ 属性(Attribute):数据(变量或常量) ▶ 方法(Method):类的函数,用于对对象进行操作或执行特定的任务 ▶ 继承(Inheritance):继承是面向对象编程中的一种重要概念,它允许你创建一个新的类,继承已存在的类的属性和方法。子类可以通过继承来共享父类的特性,并可以添加自己的特性 ▶ 多态(Polymorphism):多态是指对象可以根据不同的情境以不同的方式进行处理。它允许同一种操作应用在不同的对象上,并根据对象的类型调用相应的方法 类和对象的关系:通过类创建对象 |
定义类:
class 类名:
代码
执行的代码
…
命名规则:满足Python标识符命名规则,遵循大驼峰命名习惯
创建对象
对象名 = 类名
Python类中的self指的是调用该函数的对象
# 创建一个简单类
class Computer:
def music(self):
print("电脑客厅听音乐")
print("self:", self)
# 创建对象
computer = Computer()
print("对象地址:", computer)
# 调用类方法
computer.music()
# 创建多个对象
dell = Computer()
dell.music()
macbook = Computer()
macbook.music()
print("dell对象地址:", dell)
print("macbook对象地址:", macbook)
不同对象的地址值不一样,对应不同self也不同
属性:类或对象的特征或数据(描述其状态和行为) 类属性(Class Attributes):类属性是定义在类级别上的属性,它被所有该类的实例所共享 实例属性(Instance Attributes):定义在类的实例上的属性,不被其他实例所共享 静态属性(Static Properties):既不属于类属性也不属于实例属性的属性(使用装饰器@staticmethod将方法定义为静态方法,并通过类名直接访问和调用) 每个实例都有其自己的一组实例属性,可以在类的构造方法(init)中初始化实例属性 |
对象属性可以在类的内部直接定义,也可以在类外部通过类名进行访问和修改
外部添加对象属性:对象名.属性名 = 值
Python中,
__xx__()
的函数叫做魔法方法(具有特殊功能的函数)
▶__init__()
:初始化对象(用于固定属性值)
1.__init__()
方法在创建对象时自动 调用(不需单独手动调用)
2.__init__()
方法中的参数不需手动传递,Python解释器自动把当前对象引用过去
# 初始化对象属性
class Cups:
# 初始化属性
def __init__(self):
# 添加实例属性
self.size = 2000
self.shape = 'circle'
# 定义类方法
def print_info(self):
print(f'杯子的容量{self.size}ml,形状为{self.shape}')
# 实例化
cups = Cups()
cups.print_info()
▶ 带参数的
__init__()
方法,创建多个不同属性值的对象
# 初始化对象属性
class Cups:
# 初始化属性
def __init__(self, size, shape):
# 添加实例属性
self.size = size
self.shape = shape
# 定义类方法
def print_info(self):
print(f'杯子的容量{self.size}ml,形状为{self.shape}')
# 实例化(同时传入参数)
cups = Cups(500, 'square')
cups.print_info()
corning = Cups(1000, 'circle')
corning.print_info()
▶
__str__()
方法,打印对象时,我们只能看到对象的地址,使用__str__()
会输出此方法的返回字符串,存放解释说明性的文字
# 初始化对象属性
class Cups:
# 初始化属性
def __init__(self, size, shape):
# 添加实例属性
self.size = size
self.shape = shape
def __str__(self):
# 存放解释说明性的文字
return "这是一个杯子类!"
# 定义类方法
def print_info(self):
print(f'杯子的容量{self.size}ml,形状为{self.shape}')
# 实例化(同时传入参数)
cups = Cups(500, 'square')
cups.print_info()
corning = Cups(1000, 'circle')
corning.print_info()
print(cups)
▶
__del__()
方法,Python解释器默认自动调用
# 初始化对象属性
class Cups:
# 初始化属性
def __init__(self, size, shape):
# 添加实例属性
self.size = size
self.shape = shape
def __str__(self):
# 存放解释说明性的文字
return "这是一个杯子类!"
# 定义类方法
def print_info(self):
print(f'杯子的容量{self.size}ml,形状为{self.shape}')
def __del__(self):
print("方法以删除!")
# 实例化(同时传入参数)
cups = Cups(500, 'square')
"""
烤地瓜案例
"""
class SweetPotato:
# 初始化属性值
def __init__(self):
# 初始化时间
self.times = 0
# 初始化状态
self.status = "生的"
# 初始化调料
self.condiments = []
def cook(self, time):
""" 计算烤地瓜的时间 """
self.times += time
if 0 < self.times < 3:
# 更新地瓜状态
self.status = "生的"
elif 3 <= self.times < 5:
self.status = "半生不熟"
elif 5 <= self.times < 8:
self.status = "熟的"
elif self.times >= 8:
self.status = "烤糊了"
def add_condiments(self, condiment):
""" 添加调料"""
self.condiments.append(condiment)
def __str__(self):
return f'地瓜被烤时长{self.times}分钟,地瓜当前状态:{self.status},用户自己添加了调料{self.condiments}'
# 创建对象
pachyrhizus = SweetPotato()
pachyrhizus.add_condiments("孜然")
pachyrhizus.add_condiments("辣椒粉")
pachyrhizus.cook(10)
print(pachyrhizus)
继承:一个类(称为子类)可以继承另一个类(称为父类)的属性和方法,并且可以添加自己特定的属性和方法 特点:子类默认继承父类的所有属性和方法 实例属性(Instance Attributes):定义在类的实例上的属性,不被其他实例所共享 静态属性(Static Properties):既不属于类属性也不属于实例属性的属性(使用装饰器@staticmethod将方法定义为静态方法,并通过类名直接访问和调用) 每个实例都有其自己的一组实例属性,可以在类的构造方法(init)中初始化实例属性 经典类:不由任意内置类型派生出的类 新式类:Python2.2及以上默认的类都是新式类 在Python中,所有类默认继承object类(顶级类、基类),其他子类成为派生类 多继承:一个子类同时继承多个父类(Python支持多继承模式) |
▶ 简单继承(单继承)
"""
python继承(单继承)
"""
# 继承
class Father(object):
# 初始化
def __init__(self):
self.name = "父类已被继承"
def info(self):
print(self.name)
# 创建子类
class Child(Father):
pass
# 创建子类对象
child = Child()
# 利用子类对象调用父类方法
child.info()
▶ 简单继承(多继承)
一个子类继承多个父类时,默认使用第一个父类的同名属性和方法
方法重写:子类中重新定义父类中已有的方法(修改或扩展父类的功能)
重写规则:1. 方法名必须与父类中被重写的方法名一致
2. 参数列表必须与父类中被重写的方法参数列表保持一致(个数、顺序和类型)
子类和父类具有同名属性和方法,默认使用子类的同名属性和方法
▶ 查看类的继承关系
类的方法解析顺序:方法解析顺序MRO(Method Resolution Order)是指确定在多重继承中,方法的调用顺序的算法(基于C3算法)
C3线性化算法
子类优先:首先考虑子类,然后再考虑父类
多重继承顺序:如果有多个父类,则按照从左到右的顺序进行解析
线性化定义:对于每个类,其MRO是其直接父类列表以及它们各自的MRO的线性拓扑排序
查看方式:类名.__mro__
print(类名.__mro__)
▶ 子类调用父类方法和属性
1. 先调用子类的初始化(如果先调用父类的属性和方法会覆盖子类的属性)
2. 调用父类方法:调用父类方法时,为了使用到的属性也是父类的属性,在调用方法前先调用父类的初始化方法
"""
========================================================================================================================
技艺传承(继承)
========================================================================================================================
"""
# 父类1:师傅类
class Master(object):
def __init__(self):
print("****************Master父类初始化方法")
self.technology = '古法传承:古法煎饼果子'
def cook(self):
print("****************Master父类cook方法")
print(f'{self.technology}制饼技术')
# 父类2:学校类
class School(object):
def __init__(self):
print("****************School父类初始化方法")
self.technology = '现代技术:全自动煎饼制作技术'
def cook(self):
print("****************School父类cook方法")
print(f'{self.technology}快速制作')
# 徒弟类(继承2个父类)
class Prentice(Master, School):
def __init__(self):
print("****************Prentice子类初始化方法")
self.technology = '自研技术'
# 方法重写
def cook(self):
print("****************Prentice子类cook方法")
# 防止被父类属性覆盖
self.__init__()
print(f'全新{self.technology}制饼技术')
# 调用父类方法
def master_cook(self):
print("****************Prentice子类调用父类Master方法属性")
# 调用父类方法前,先调用父类初始化方法(确保方法中使用的属性是父类的)
Master.__init__(self)
# 再调用父类方法
Master.cook(self)
def school_cook(self):
print("****************Prentice子类调用父类School方法属性")
# 调用父类方法前,先调用父类初始化方法(确保方法中使用的属性是父类的)
School.__init__(self)
# 再调用父类方法
School.cook(self)
# 多层继承
class Apprentice(Prentice):
pass
# 创建徒弟类实例
pupil = Prentice()
print("="*80)
# 方法调用(继承于父类)
pupil.cook()
print("="*80)
print("访问父类属性:", pupil.technology)
print("="*80)
# 查看python类的继承关系
print("Python继承关系:", Prentice.__mro__)
print("="*80)
pupil.master_cook()
# 父类会覆盖子类属性
pupil.cook()
print("="*80)
# 多层继承
after_pupil = Apprentice()
after_pupil.cook()
after_pupil.master_cook()
after_pupil.school_cook()
print("="*80)
# 继承
class Father(object):
# 初始化
def __init__(self):
self.name = "Father父类"
def info(self):
print(self.name)
def function(self):
print(f'{self.name}的功能')
# 创建子类
class Child(Father):
def __init__(self):
self.name = 'Child子类'
# super()方法适用于单继承
def f(self):
self.__init__()
# 第一种写法
Father.__init__(self)
Father.function(self)
def f1(self):
# 第二种写法
super(Child, self).__init__()
super(Child, self).function()
def f2(self):
# 简写
super().__init__()
super().function()
▶ 私有:私有属性指的是以双下划线"__"开头的属性。不继承给子类(对某些方法和属性予以保护)
私有属性:__属性名
私有方法:__方法名
获取和修改私有属性
一般定义函数名为get_xx来获取私有属性,set_xx用来修改私有属性
class MyClass:
def __init__(self):
self.__private_attr = 42
obj = MyClass()
print(obj._MyClass__private_attr) # 输出: 42
class MyClass:
def __init__(self):
self.__private_attr = 42
def get_private_attr(self):
return self.__private_attr
obj = MyClass()
print(obj.get_private_attr()) # 输出: 42
class MyClass:
def __init__(self):
self.__private_attr = 42
obj = MyClass()
obj._MyClass__private_attr = 100 # 修改私有属性的值
print(obj._MyClass__private_attr) # 输出: 100
class MyClass:
def __init__(self):
self.__private_attr = 42
def set_private_attr(self, value):
self.__private_attr = value
obj = MyClass()
obj.set_private_attr(100) # 修改私有属性的值
print(obj._MyClass__private_attr) # 输出: 100