Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态

简介: Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态

前言

    Python面向对象编程的核心在于封装、继承和多态。封装隐藏细节,继承实现重用,多态提升灵活。本文将深入解析这三大要素,助您掌握面向对象编程的精髓。面向对象基础详解请看上一篇,点这!!!


一、面向对象三要素

继承:子类继承父类,子类拥有了父类的属性和方法。降低代码的重复性

封装:将对象的属性和实现细节进行封装,仅对外提供公共的访问方式。提高代码 的安全性;使用私有属性和私有方法实现封装

多态:不同的对象调用父类相同的方法获取不同的执行结果。多态实现需要:继承、方法重写


二、继承

1.概念

概念:子类继承父类,子类拥有了父类的属性和方法;降低代码的重复性

继承–>派生 子类–>派生类 父类–>基类

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.简单继承

# 简单继承
class A:
    def __init__(self):
        self.money = "一个亿"
    def car(self):
        print("一辆黑色的帕拉梅拉")
class B(A):
    pass
b = B()
print(b.money)   # 子类继承了父类,子类对象可以获取父类的属性
b.car()  # 子类继承了父类,子类对象可以调用父类的方法

3.单继承

# 单继承:一个子类继承一个父类
class Master:
    def __init__(self):
        self.kongfu = "古法煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出古法煎饼果子")
class Cat(Master):
    pass
cat = Cat()
print(cat.kongfu)
cat.make_cake()

4.多继承

# 多继承:一个子类继承多个父类
class Master:
    def __init__(self):
        self.kongfu = "古法煎饼果子配方"
        self.m_money = "100"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出古法煎饼果子")
    def master_house(self):
        print("老师傅的茅草屋")
class School:
    def __init__(self):
        self.kongfu = "现代煎饼果子配方"
        self.s_money = "1000"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出现代煎饼果子")
    def school_house(self):
        print("学校的宿舍")
class Cat(School,Master):
    pass
cat = Cat()
print(cat.kongfu)
cat.make_cake()
cat.master_house()
cat.school_house()
print(cat.s_money)
# print(cat.m_money)
# 多继承的继承顺序   __mro__
# 语法:子类.__mro__
print(Cat.__mro__)
- 多继承可以继承多个父类,也继承了所有父类的属性和方法
- 注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性**mro**的顺序来查找)
- 多个父类中,不重名的方法,不会有任何影响。

5.单继承的多层继承

# 多继承:一个子类继承多个父类
# 单继承的多层继承:
class GrandFather:
    def __init__(self):
        self.money = "一个亿"
    def house(self):
        print("一栋中式装修风格的大别墅")
class Father(GrandFather):
    def __init__(self):
        self.money = "两个亿"
    def house(self):
        print("一栋欧式装修风格的大别墅")
    # 获取grandfather的money属性
    def get_grand_money(self):
        # 第一种方式:类名.__init__(self)
        # 第二种方式:super().__init__()
        super().__init__()
        print(f"获取父类的money值为:{self.money}")
    # 调用grandfather的house方法
    def get_grand_house(self):
        # 第一种方式:类名.方法名()
        # 第二种方式:super().方法名()
        super().house()
class Son(Father):
    def __init__(self):
        self.money = "10"
    def house(self):
        print("学校的宿舍")
    # 子类获取父类的属性
    def get_father_money(self):
        # 第一种方式:类名.__init__(self)
        # 第二种方式:super().__init__()
        super().__init__()
        print(f"获取父类的money值为:{self.money}")
    # 子类调用父类的方法
    def get_father_house(self):
        # 第一种方式:类名.方法名()
        # 第二种方式:super().方法名()
        super().house()
son = Son()
print(son.money)
son.house()
son.get_father_money()
son.get_father_house()
son.get_grand_money()
son.get_grand_house()

6.子类重写父类方法

# 子类重写父类同名方法
class Master:
    def __init__(self):
        self.kongfu = "古法煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出古法煎饼果子")
class School:
    def __init__(self):
        self.kongfu = "现代煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出现代煎饼果子")
class Cat(School,Master):
    # 在子类中定义与父类相同名字的属性和方法
    def __init__(self):
        self.kongfu = "猫式煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出猫式煎饼果子")
# 如果子类和父类的方法名和属性名相同,则默认使用子类的
cat = Cat()
print(cat.kongfu)   # 子类与父类有相同名字的属性,默认使用子类的属性
cat.make_cake() # 子类与父类有相同名字的方法,默认调用子类的方法
# 多继承的继承顺序   __mro__
# 语法:子类.__mro__
print(Cat.__mro__)

7.子类获取父类的属性和方法

# 子类调用父类同名属性和方法
class Master:
    def __init__(self):
        self.kongfu = "古法煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出古法煎饼果子")
class School:
    def __init__(self):
        self.kongfu = "现代煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出现代煎饼果子")
class Cat(School,Master):
    # 在子类中定义与父类相同名字的属性和方法
    def __init__(self):
        self.kongfu = "猫式煎饼果子配方"
    def make_cake(self):
        print(f"使用{self.kongfu}制作出猫式煎饼果子")
    # 调用School类中的同名属性和方法
    # super()在多继承中只能获取第一个父类的同名属性和方法
    def get_school(self):
        # 获取父类同名属性:super().__init__()
        super().__init__()
        print(f"获取到的配方为{self.kongfu}")
        # 调用父类同名方法:super().方法名()
        super().make_cake()
    # 调用Master类中的同名属性和方法
    # 类名.的方式可以获取任意一个父类的同名属性和方法
    def get_master(self):
        # 获取父类同名属性:类名.__init__(self)
        Master.__init__(self)
        print(f"获取到的配方为{self.kongfu}")
        # 调用父类同名方法:类名.方法(self)
        Master.make_cake(self)
cat = Cat()
cat.get_school()
cat.get_master()

注意:

在不进行方法重写和获取方法之前
如果子类继承了一个父类,且子类中没有init。则初始化父类的init,获取父类的属性
如果子类继承了多个父类,且子类中没有init。则初始化第一个父类的init,获取第一个父类的属性
如果子类继承了多个父类,且子类中有init。则初始化子类本身的init,所有的父类的属性都无法获取

三、封装

1.概念

将对象的属性和实现细节隐藏起来,仅对外提供公共访问方式。提高代码的安全性

使用私有属性和私有方法实现

2.私有属性

2.1定义私有属性

class MyCls:
    def __init__(self):
        self.money = 100
        # 将属性设置为私有属性   在属性名前__
        self.__mimi = "我有一个小秘密"
my = MyCls()
print(my.__mimi)  # 对象获取不到私有属性

2.2 获取私有属性

class MyCls:
    def __init__(self):
        self.money = 100
        # 将属性设置为私有属性   在属性名前__
        self.__mimi = "我有一个小秘密"
    # 获取私有属性:通过定义公共的实例方法,在实例方法中使用私有属性
    # 私有属性只是不能在类外获取,但是可以提供在类内部进行使用;用于处理类内部的操作
    def get_mimi(self):
        print(f"获取到的私房钱为:{self.__mimi}")
my = MyCls()
my.get_mimi()

2.3 修改私有属性的值

class MyCls:
    def __init__(self):
        # 将属性设置为私有属性   在属性名前__
        self.__mimi = "我有一个小秘密"
    # 修改私有属性的值:通过定义公共的实例方法,在实例方法中获取私有属性,重新赋值
    def set_mimi(self,str1):
        self.__mimi = str1
        print(f"获取到的秘密为:{self.__mimi}")
my = MyCls()
my.set_mimi("嘿嘿嘿嘿嘿嘿")

3.私有方法

3.1 定义私有方法

class MyCls:
    # 将方法设置为私有方法    在方法名前__
    def __house(self):
        print("我有一个大别墅")
my = MyCls()
my.__house()   # 对象无法调用私有方法

3.2 调用私有方法

class MyCls:
    # 将方法设置为私有方法    在方法名前__
    def __house(self):
        print("我有一个大别墅")
    # 调用私有方法:通过定义公共的实例方法,在公共的方法中调用私有方法
    def get_house(self):
        # 调用私有方法-->实例方法
        self.__house()
my = MyCls()
my.get_house()

4.总结

关于私有属性和私有方法的总结:
私有权限:在属性和方法名前边加上两个下划线 __
1. 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
2. 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
3. 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。

四、多态

1.概念

不同的对象调用父类相同的方法获取到不同的执行结果

多态的实现需要建立在继承方法重写的基础上

2.简单案例

class Animal:
    def bark(self):
        print("动物叫")
class Dog(Animal):
    def bark(self):
        print("小狗汪汪叫")
class Cat(Animal):
    def bark(self):
        print("小猫喵喵叫")
dog = Dog()
cat = Cat()
dog.bark()
cat.bark()

五、补充

1.类对象

# 定义一个英雄类
class Hero:
    # 定义实例属性
    def __init__(self,name):
        self.name = name
    # 定义实例方法
    def kill(self):
        print(f"{self.name}英雄会杀人")
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
# 实例对象获取实例属性
print(luban.name)
# 实例对象调用实例方法
luban.kill()
# 类对象-->类本身-->类名
print(Hero)
# 类对象无法获取实例属性
# 类对象无法调用实例方法

2.类属性

# 定义一个英雄类
class Hero:
    # 类属性:直接在定义类的类名下 属性名 = 属性值
    class_name = "英雄类"
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
# 实例对象获取类属性
print(luban.class_name)
# 类对象-->类本身-->类名
print(Hero)
# 类对象获取类属性
print(Hero.class_name)

3.类方法

# 定义一个英雄类
class Hero:
    # 定义类方法,需要借助装饰器 classmethod  实现定义类方法
    # 装饰器用法:想要将哪一个方法创建为类方法,在该方法上方 @装饰器
    # 创建好的类方法自带参数cls;cls-->类对象本身
    @classmethod
    def run(cls):
        print("英雄会跑")
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
# 实例对象调用类方法
luban.run()
# 类对象-->类本身-->类名
print(Hero)
# 类对象调用类方法
Hero.run()

4.静态方法

# 定义一个英雄类
class Hero:
    # 定义静态方法,需要借助装饰器   staticmethod  实现定义静态方法
    @staticmethod
    def eat():
        print("英雄会吃")
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
# 实例对象调用静态方法
luban.eat()
# 类对象-->类本身-->类名
print(Hero)
# 类对象调用静态方法
Hero.eat()

5.属性在方法中的使用

# 定义一个英雄类
class Hero:
    # 类属性:直接在定义类的类名下 属性名 = 属性值
    class_name = "英雄类"
    # 定义实例属性
    def __init__(self,name):
        self.name = name
    # 定义实例方法
    def kill(self):
        # 实例对象可以获取实例属性,实例方法中使用实例属性   self.实例属性名
        # 实例对象可以获取类属性,实例方法中使用类属性    self.类属性名
        print(f"{self.name}英雄属于{self.class_name}")
    # 定义类方法,需要借助装饰器 classmethod  实现定义类方法
    # 装饰器用法:想要将哪一个方法创建为类方法,在该方法上方 @装饰器
    # 创建好的类方法自带参数cls;cls-->类对象本身
    @classmethod
    def run(cls):
        # 类对象可以获取类属性但是不能获取实例属性
        # 在类方法中可以使用类属性,不能使用实例属性
        # 类方法中使用类属性   cls.类属性名
        print(f"英雄会跑,属于{cls.class_name}")
    # 定义静态方法,需要借助装饰器   staticmethod  实现定义静态方法
    # 静态方法中不提供任何对象参数,无法调用实例属性和实例方法
    @staticmethod
    def eat():
        print("英雄会吃")
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
# 实例对象获取实例属性
print(luban.name)
# 实例对象调用实例方法
luban.kill()
# 实例对象获取类属性
print(luban.class_name)
# 实例对象调用类方法
luban.run()
# 实例对象调用静态方法
luban.eat()
# 类对象-->类本身-->类名
print(Hero)
# 类对象无法获取实例属性
# 类对象无法调用实例方法
# 类对象获取类属性
print(Hero.class_name)
# 类对象调用类方法
Hero.run()
# 类对象调用静态方法
Hero.eat()

6.在方法中修改属性

6.1 在实例方法中修改数据

# 定义一个英雄类
class Hero:
    # 类属性:直接在定义类的类名下 属性名 = 属性值
    class_name = "英雄类"
    # 定义实例属性
    def __init__(self,name):
        self.name = name
    # 定义实例方法
    def kill(self):
        # 在实例方法中获取属性
        # 实例对象可以获取实例属性,实例方法中使用实例属性   self.实例属性名
        # 实例对象可以获取类属性,实例方法中使用类属性    self.类属性名
        print(f"{self.name}英雄属于{self.class_name}")
        # 在实例方法中修改属性的值
        # 修改实例属性的值    self.实例属性名 = 新值
        self.name = "卤蛋"
        # 使用实例对象修改类属性的值 == 创建新的实例属性class_name
        # self.类属性名 = 新值
        self.class_name = "超人类"
# 实例化一个对象-->实例对象
luban = Hero("鲁班")
luban.kill()   # "鲁班英雄属于英雄类"
print(luban.name)   # "卤蛋"
print(luban.class_name)   # "超人类"
print(Hero.class_name)   # "英雄类"
如果需要在类外修改**类属性**,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的**实例属性**,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是**实例属性**,除非删除了该实例属性。

6.2 在类方法中修改属性

# 定义一个英雄类
class Hero:
    # 类属性:直接在定义类的类名下 属性名 = 属性值
    class_name = "英雄类"
    # 定义类方法,需要借助装饰器 classmethod  实现定义类方法
    # 装饰器用法:想要将哪一个方法创建为类方法,在该方法上方 @装饰器
    # 创建好的类方法自带参数cls;cls-->类对象本身
    @classmethod
    def run(cls):
        # 类对象可以获取类属性但是不能获取实例属性
        # 在类方法中可以使用类属性,不能使用实例属性
        # 类方法中使用类属性   cls.类属性名
        print(f"英雄会跑,属于{cls.class_name}")
        # 在类方法中修改类属性    cls.类属性名 = 属性值
        cls.class_name = "超人类"
Hero.run()    # "英雄会跑,属于英雄类"
print(Hero.class_name)   # "超人类"

7.总结

实例对象:实例属性、实例方法、类属性、类方法、静态方法
类对象:类属性、类方法、静态方法
1. 从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;
2. 实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
3. 静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引用
在平时定义类中实例方法最常用
类方法-->修改类属性的值、工厂模式
静态方法-->只是想让功能代码存放在类中,使用静态方法即可
相关文章
|
3月前
|
数据采集 JSON API
深入解析:使用 Python 爬虫获取淘宝店铺所有商品接口
本文介绍如何使用Python结合淘宝开放平台API获取指定店铺所有商品数据。首先需注册淘宝开放平台账号、创建应用并获取API密钥,申请接口权限。接着,通过构建请求、生成签名、调用接口(如`taobao.items.search`和`taobao.item.get`)及处理响应,实现数据抓取。代码示例展示了分页处理和错误处理方法,并强调了调用频率限制、数据安全等注意事项。此技能对开发者和数据分析师极具价值。
|
4月前
|
存储 索引 Python
Python入门:6.深入解析Python中的序列
在 Python 中,**序列**是一种有序的数据结构,广泛应用于数据存储、操作和处理。序列的一个显著特点是支持通过**索引**访问数据。常见的序列类型包括字符串(`str`)、列表(`list`)和元组(`tuple`)。这些序列各有特点,既可以存储简单的字符,也可以存储复杂的对象。 为了帮助初学者掌握 Python 中的序列操作,本文将围绕**字符串**、**列表**和**元组**这三种序列类型,详细介绍其定义、常用方法和具体示例。
Python入门:6.深入解析Python中的序列
|
4月前
|
存储 Linux iOS开发
Python入门:2.注释与变量的全面解析
在学习Python编程的过程中,注释和变量是必须掌握的两个基础概念。注释帮助我们理解代码的意图,而变量则是用于存储和操作数据的核心工具。熟练掌握这两者,不仅能提高代码的可读性和维护性,还能为后续学习复杂编程概念打下坚实的基础。
Python入门:2.注释与变量的全面解析
|
3月前
|
机器学习/深度学习 数据采集 自然语言处理
基于Python的情感分析与情绪识别技术深度解析
本文探讨了基于Python的情感分析与情绪识别技术,涵盖基础概念、实现方法及工业应用。文中区分了情感分析与情绪识别的核心差异,阐述了从词典法到深度学习的技术演进,并通过具体代码展示了Transformers架构在细粒度情感分析中的应用,以及多模态情绪识别框架的设计。此外,还介绍了电商评论分析系统的构建与优化策略,包括领域自适应训练和集成学习等方法。未来,随着深度学习和多模态数据的发展,该技术将更加智能与精准。
214 1
|
3月前
|
Python
Python 高级编程与实战:深入理解面向对象与并发编程
本文深入探讨Python的高级特性,涵盖面向对象编程(继承、多态、特殊方法、类与实例属性)、异常处理(try-except、finally)和并发编程(多线程、多进程、异步编程)。通过实战项目如聊天服务器和异步文件下载器,帮助读者掌握这些技术,编写更复杂高效的Python程序。
|
4月前
|
存储 人工智能 程序员
通义灵码AI程序员实战:从零构建Python记账本应用的开发全解析
本文通过开发Python记账本应用的真实案例,展示通义灵码AI程序员2.0的代码生成能力。从需求分析到功能实现、界面升级及测试覆盖,AI程序员展现了需求转化、技术选型、测试驱动和代码可维护性等核心价值。文中详细解析了如何使用Python标准库和tkinter库实现命令行及图形化界面,并生成单元测试用例,确保应用的稳定性和可维护性。尽管AI工具显著提升开发效率,但用户仍需具备编程基础以进行调试和优化。
419 9
|
4月前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
113 10
|
5月前
|
运维 Shell 数据库
Python执行Shell命令并获取结果:深入解析与实战
通过以上内容,开发者可以在实际项目中灵活应用Python执行Shell命令,实现各种自动化任务,提高开发和运维效率。
161 20
|
5月前
|
存储 算法 安全
控制局域网上网软件之 Python 字典树算法解析
控制局域网上网软件在现代网络管理中至关重要,用于控制设备的上网行为和访问权限。本文聚焦于字典树(Trie Tree)算法的应用,详细阐述其原理、优势及实现。通过字典树,软件能高效进行关键词匹配和过滤,提升系统性能。文中还提供了Python代码示例,展示了字典树在网址过滤和关键词屏蔽中的具体应用,为局域网的安全和管理提供有力支持。
104 17
|
4月前
|
存储 数据采集 JSON
Python爬取某云热歌榜:解析动态加载的歌曲数据
Python爬取某云热歌榜:解析动态加载的歌曲数据

推荐镜像

更多