Python面向对象编程

Python面向对象

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

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

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


命名规则:满足Python标识符命名规则,遵循大驼峰命名习惯
创建对象
对象名 = 类名
Python类中的self指的是调用该函数的对象

Python面向对象编程_第1张图片

# 创建一个简单类
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也不同

Python面向对象编程_第2张图片

3. 属性
属性:类或对象的特征或数据(描述其状态和行为)
类属性(Class Attributes):类属性是定义在类级别上的属性,它被所有该类的实例所共享
实例属性(Instance Attributes):定义在类的实例上的属性,不被其他实例所共享
静态属性(Static Properties):既不属于类属性也不属于实例属性的属性(使用装饰器@staticmethod将方法定义为静态方法,并通过类名直接访问和调用)
每个实例都有其自己的一组实例属性,可以在类的构造方法(init)中初始化实例属性

对象属性可以在类的内部直接定义,也可以在类外部通过类名进行访问和修改
外部添加对象属性:对象名.属性名 = 值

Python面向对象编程_第3张图片

4. 魔法方法

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)
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 = 42

obj = MyClass()
print(obj._MyClass__private_attr)  # 输出: 42
  • 定义一个公有的getter方法来获取私有属性的值
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
  • 定义一个公有的setter方法来修改私有属性的值
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

你可能感兴趣的:(AI,python,开发语言)