Python面向对象编程

Python面向对象

        • [1. 面向对象](#1. 面向对象)
        • [2. 创建简单类](#2. 创建简单类)
        • [3. 属性](#3. 属性)
        • [4. 魔法方法](#4. 魔法方法)
        • [5. 继承](#5. 继承)
1. 面向对象

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 面向对象编程 OOP :(Object-Oriented Programming)是一种将数据和相关操作封装在一起的编程方式 :对一系列具有相同特征和行为的食物的统称(一个抽象概念,不是真实存在的事务) 对象 :由类创建出来的真实存在的事务 特征即属性, 行为即方法   ▶ 类(Class) :类是对象的蓝图或模板,定义了对象的属性和方法   ▶ 对象(Object) :类的实例化结果,根据类创建的具体实体   ▶ 属性(Attribute) :数据(变量或常量)   ▶ 方法(Method) :类的函数,用于对对象进行操作或执行特定的任务   ▶ 继承(Inheritance) :继承是面向对象编程中的一种重要概念,它允许你创建一个新的类,继承已存在的类的属性和方法。子类可以通过继承来共享父类的特性,并可以添加自己的特性   ▶ 多态(Polymorphism) :多态是指对象可以根据不同的情境以不同的方式进行处理。它允许同一种操作应用在不同的对象上,并根据对象的类型调用相应的方法 类和对象的关系:通过类创建对象 |

2. 创建简单类

定义类:
    class 类名:
     代码
     执行的代码
     ...

命名规则:满足Python标识符命名规则,遵循大驼峰命名习惯

创建对象
对象名 = 类名
Python类中的self指的是调用该函数的对象

python 复制代码
# 创建一个简单类
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解释器自动把当前对象引用过去

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__()方法,创建多个不同属性值的对象

python 复制代码
# 初始化对象属性
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__()会输出此方法的返回字符串,存放解释说明性的文字

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}')
        
# 实例化(同时传入参数)
cups = Cups(500, 'square')
cups.print_info()

corning = Cups(1000, 'circle')
corning.print_info()

print(cups)

__del__()方法,Python解释器默认自动调用

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')
  • 烤地瓜案例
python 复制代码
"""
烤地瓜案例
"""


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)
5. 继承

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 继承 :一个类(称为子类)可以继承另一个类(称为父类)的属性和方法,并且可以添加自己特定的属性和方法 特点 :子类默认继承父类的所有属性和方法 实例属性(Instance Attributes) :定义在类的实例上的属性,不被其他实例所共享 静态属性(Static Properties) :既不属于类属性也不属于实例属性的属性(使用装饰器@staticmethod将方法定义为静态方法,并通过类名直接访问和调用) 每个实例都有其自己的一组实例属性,可以在类的构造方法(init)中初始化实例属性 经典类 :不由任意内置类型派生出的类 新式类 :Python2.2及以上默认的类都是新式类 在Python中,所有类默认继承object类(顶级类、基类),其他子类成为派生类 多继承 :一个子类同时继承多个父类(Python支持多继承模式) |

▶ 简单继承(单继承)

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__

python 复制代码
print(类名.__mro__)

▶ 子类调用父类方法和属性

1. 先调用子类的初始化(如果先调用父类的属性和方法会覆盖子类的属性)

2. 调用父类方法:调用父类方法时,为了使用到的属性也是父类的属性,在调用方法前先调用父类的初始化方法

python 复制代码
"""
========================================================================================================================
技艺传承(继承)
========================================================================================================================
"""


# 父类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调用父类的方法属性
python 复制代码
# 继承
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用来修改私有属性

  • 访问私有属性
python 复制代码
class MyClass:
    def __init__(self):
        self.__private_attr = 42

obj = MyClass()
print(obj._MyClass__private_attr)  # 输出: 42
  • 定义一个公有的getter方法来获取私有属性的值
python 复制代码
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
  • 修改私有属性
python 复制代码
class MyClass:
    def __init__(self):
        self.__private_attr = 42

obj = MyClass()
obj._MyClass__private_attr = 100  # 修改私有属性的值
print(obj._MyClass__private_attr)  # 输出: 100
  • 定义一个公有的setter方法来修改私有属性的值
python 复制代码
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
相关推荐
I_Am_Me_8 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
重生之我是数学王子19 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
Ai 编码助手20 分钟前
使用php和Xunsearch提升音乐网站的歌曲搜索效果
开发语言·php
学习前端的小z24 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
神仙别闹32 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE33 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
zwjapple1 小时前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
前端每日三省1 小时前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
好看资源平台1 小时前
网络爬虫——综合实战项目:多平台房源信息采集与分析系统
爬虫·python