Python面向对象
- 1. 面向对象
- 2. 创建简单类
- 3. 属性
- 4. 魔法方法
- 5. 继承
1. 面向对象
面向对象编程 OOP:(Object-Oriented Programming)是一种将数据和相关操作封装在一起的编程方式 类:对一系列具有相同特征和行为的食物的统称(一个抽象概念,不是真实存在的事务) 对象:由类创建出来的真实存在的事务 特征即属性, 行为即方法 ▶ 类(Class):类是对象的蓝图或模板,定义了对象的属性和方法 ▶ 对象(Object):类的实例化结果,根据类创建的具体实体 ▶ 属性(Attribute):数据(变量或常量) ▶ 方法(Method):类的函数,用于对对象进行操作或执行特定的任务 ▶ 继承(Inheritance):继承是面向对象编程中的一种重要概念,它允许你创建一个新的类,继承已存在的类的属性和方法。子类可以通过继承来共享父类的特性,并可以添加自己的特性 ▶ 多态(Polymorphism):多态是指对象可以根据不同的情境以不同的方式进行处理。它允许同一种操作应用在不同的对象上,并根据对象的类型调用相应的方法 类和对象的关系:通过类创建对象 |
2. 创建简单类
定义类:
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也不同
3. 属性
属性:类或对象的特征或数据(描述其状态和行为) 类属性(Class Attributes):类属性是定义在类级别上的属性,它被所有该类的实例所共享 实例属性(Instance Attributes):定义在类的实例上的属性,不被其他实例所共享 静态属性(Static Properties):既不属于类属性也不属于实例属性的属性(使用装饰器@staticmethod将方法定义为静态方法,并通过类名直接访问和调用) 每个实例都有其自己的一组实例属性,可以在类的构造方法(init)中初始化实例属性 |
对象属性可以在类的内部直接定义,也可以在类外部通过类名进行访问和修改
外部添加对象属性:对象名.属性名 = 值
4. 魔法方法
Python中,
__xx__()
的函数叫做魔法方法(具有特殊功能的函数)
▶__init__()
:初始化对象(用于固定属性值)
1.__init__()
方法在创建对象时自动 调用(不需单独手动调用)
2.__init__()
方法中的参数不需手动传递,Python解释器自动把当前对象引用过去
# 初始化对象属性
class Cups:# 初始化属性def __init__(self):# 添加实例属性self.size = 2000self.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 = sizeself.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 = sizeself.shape = shapedef __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 = sizeself.shape = shapedef __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 += timeif 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)
5. 继承
继承:一个类(称为子类)可以继承另一个类(称为父类)的属性和方法,并且可以添加自己特定的属性和方法 特点:子类默认继承父类的所有属性和方法 实例属性(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)
- super调用父类的方法属性
# 继承
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 = 42obj = MyClass()
print(obj._MyClass__private_attr) # 输出: 42
- 定义一个公有的getter方法来获取私有属性的值
class MyClass:def __init__(self):self.__private_attr = 42def get_private_attr(self):return self.__private_attrobj = MyClass()
print(obj.get_private_attr()) # 输出: 42
- 修改私有属性
class MyClass:def __init__(self):self.__private_attr = 42obj = MyClass()
obj._MyClass__private_attr = 100 # 修改私有属性的值
print(obj._MyClass__private_attr) # 输出: 100
- 定义一个公有的setter方法来修改私有属性的值
class MyClass:def __init__(self):self.__private_attr = 42def set_private_attr(self, value):self.__private_attr = valueobj = MyClass()
obj.set_private_attr(100) # 修改私有属性的值
print(obj._MyClass__private_attr) # 输出: 100