Python封装、继承和多态

news2025/1/17 21:45:38

Python 语言在设计之初,就定位为一门面向对象的编程语言,“Python 中一切皆对象”。同时,Python 也支持面向对象的三大特征:封装、继承和多态。

一、封装

封装(Encapsulation),即在设计类时,刻意地将一些属性和方法隐藏在类的内部,这样在使用此类时,将无法直接以“类对象.属性名”(或者“类对象.方法名(参数)”)的形式调用这些属性(或方法),而只能用未隐藏的类方法间接操作这些隐藏的属性和方法。

类的封装机制保证了类内部数据结构的完整性,提高了程序的可维护性,还可以提高代码的复用性。

1、Python类如何进行封装

Python 没有提供 public、private 这些修饰符,为了实现类的封装,而是采取了下面的方法:

  • 默认情况下,Python 类中的变量和方法都是公有的,它们的名称前都没有下划线(_);
  • 如果以单下划线“_”开头,则是类属性或者类方法;
  • 如果以双下划线“__”开头,则是私有变量或者私有方法。

注意:

  • Python 类中还有以双下划线开头和结尾的类方法(例如类的构造函数__init__(self)),这些都是 Python 内部定义的,用于 Python 内部调用。我们自己定义类属性或者类方法时,不要使用这种格式。

示例代码如下:

class MyClass:

    def setname(self, name):
        if len(name) < 3:
            raise ValueError('名称长度必须大于3!')
        self.__name = name

    def getname(self):
        return self.__name

    # 为 name 配置 setter 和 getter 方法
    name = property(getname, setname)

    age = None

    # 定义公有方法
    def m1(self):
        # 调用私有方法
        print("m1 调用私有方法:", self.__privateM1())
        return 'hello MyClass'

    # 定义个私有方法
    def __privateM1(self):
        print(self.name, self.age)


obj = MyClass()

obj.name = "赵子龙"
obj.age = 18
print(obj.getname())
print(obj.age)
print("---------")
print(obj.m1())

在这里插入图片描述

二、继承

Python 支持类的单继承和多继承。

  • 实现继承的类称为子类,被继承的类称为父类(也可称为基类、超类)。
  • 类继承父类时,只需在定义子类时,将父类(可以是多个)放在子类之后的圆括号里即可。
  • 如果该类没有显式指定继承自哪个类,则默认继承 object 类(object 类是 Python 中所有类的父类,即要么是直接父类,要么是间接父类)。

1、单继承

子类(派生类)的定义语法如下:

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>
  • 子类(DerivedClassName类)会继承父类(BaseClassName基类)的属性和方法(包括私有的)。

示例代码如下:

class People:
    # 定义基本属性
    name = ''
    age = 0
    # 定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0

    # 定义构造方法
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w

    def speak(self):
        print("%s 说: 我 %d 岁。" % (self.name, self.age))


# 单继承示例
class Student(People):
    grade = ''

    def __init__(self, n, a, w, g):
        # 调用父类的构函
        People.__init__(self, n, a, w)
        self.grade = g

    # 重写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁,职业:%s" % (self.name, self.age, self.grade))

s = Student('赵云',18,60.0,"小学生")
s.speak() # 赵云 说: 我 18 岁,职业:王者

2、多继承

Python支持多继承形式。多继承的类定义语法如下:

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

使用多继承经常需要面临的问题是,多个父类中包含同名的类方法,而在子类使用时未指定重写该方法时。注意圆括号中父类的顺序。即方法在子类中未找到时,从左到右查找父类中是否包含方法。

示例代码如下:

# 类定义
class People:
    # 定义基本属性
    name = ''
    age = 0
    # 定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0

    # 定义构造方法
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w

    def speak(self):
        print("%s 说: 我 %d 岁。" % (self.name, self.age))


# 单继承
class Student(People):
    grade = ''

    def __init__(self, n, a, w, g):
        # supper调用父类的构造方法,无需手动给 self 传值
        super().__init__(n, a, w)
        self.grade = g

    # 覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁,职业:%s" % (self.name, self.age, self.grade))


# 职业类
class Profession():
    prof = ''

    def __init__(self, prof):
        self.prof = prof

    def speakProf(self):
        print("职业段位:{} ".format(self.prof))


# 多重继承
class Game(Student, Profession):
    gameName = ''

    def __init__(self, gameName, name, age, weight, g, prof):
        self.gameName = gameName
        print("欢迎进入 {}".format(self.gameName))
        # 类名调用父类的构造方法,需手动给 self 传值
        Student.__init__(self, name, age, weight, g)
        Profession.__init__(self, prof)


obj = Game("王者荣耀", "赵子龙", 18, 60.5, "小学生", "王者")
obj.speak()  # 方法名同,默认调用的是在括号中参数位置排前父类的方法
obj.speakProf()

在这里插入图片描述

super() 函数是用于调用父类的一个方法。推荐大家使用这种格式:

super().__init__(...)

3、方法重写

方法重写,方法又称覆盖,是指如果父类方法的功能不能满足子类的需求时,子类可以对已有方法的内部实现进行修改。

示例代码如下:

class Parent:  # 定义父类
    def myMethod(self):
        print('调用父类方法')


class Child(Parent):  # 定义子类
    def myMethod(self):
        print('调用子类方法')


c = Child()  # 子类实例
c.myMethod()  # 子类调用重写方法
Parent.myMethod(c) # 用父类名调用父类方法

三、多态

多态:就是同一种行为对不同的子类[对象]有不同的行为表现。

要想实现多态,必须满足两个前提条件:

  1. 继承:多态一定是发生在子类和父类之间
  2. 重写:子类重写了父类的方法

示例代码如下:

class CLanguage:
    def say(self):
        print("调用的是 Clanguage 类的say方法")
class CPython(CLanguage):
    def say(self):
        print("调用的是 CPython 类的say方法")
class CLinux(CLanguage):
    def say(self):
        print("调用的是 CLinux 类的say方法")

a = CLanguage()
a.say()
a = CPython()
a.say()
a = CLinux()
a.say()

在这里插入图片描述

四、枚举类

Python 3.4 中新增加了 Enum 枚举类。对于某些实例化对象个数固定的类,可以用枚举类来定义。

枚举类的每个成员都由 2 部分组成,分别为 name 和 value,其中 name 属性值为该枚举值的变量名(如 red),value 代表该枚举值的序号(序号通常从 1 开始)。

注意:

  • 枚举类不能用来实例化对象,但这并不妨碍我们访问枚举类中的成员。
  • 枚举类成员之间不能比较大小,但可以用 == 或者 is 进行比较是否相等。
  • 枚举类中各个成员的值,不能在类的外部做任何修改。

1、创建枚举类

(1)通过继承 Enum 类的方法创建枚举类

from enum import Enum

class SexEnum(Enum):
    # 指定value值,通常从 1 开始
    male = 1
    female = 2
    other = 3

(2)使用 Enum() 函数创建枚举类

from enum import Enum

# 创建一个枚举类
SexEnum = Enum("SexEnum", ('male', 'female', 'other'))

2、访问枚举类成员

(1)访问枚举成员的 3 种方式

print(SexEnum.male)
print(SexEnum['female'])
print(SexEnum(3))

sex = SexEnum.male
print(sex.name, "--", sex.value)

在这里插入图片描述

(2)遍历枚举类中所有成员的 2 种方式:

  • 遍历枚举类
  • 遍历 __members__ 属性

枚举类提供了一个 __members__ 属性,该属性是一个包含枚举类中所有成员的字典,通过遍历该属性,可以访问枚举类中的所有成员。

# 遍历枚举类
for sex in SexEnum:
    print(sex.name, "--", sex.value)

print("--------")
# 遍历 __members__ 属性
for name, member in SexEnum.__members__.items():
    print(name, "->", member)

在这里插入图片描述

3、@unique 装饰器

枚举类中各个成员必须保证 name 互不相同,但 value 可以相同。value 相同时,对于程序会有一定的问题,开发中一般不推荐 value 相同。

Python 提供了 @unique 装饰器,这样当枚举类中出现相同值的成员时,程序会报 ValueError 错误。

#引入 unique
from enum import Enum, unique

# 创建一个枚举类,添加 unique 装饰器
@unique
class SexEnum(Enum):
    # 指定value值,通常从 1 开始
    male = 1
    female = 2
    other = 3

– 求知若饥,虚心若愚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

讲师邀请 | 在 DevData Talks,开放务实地聊聊研发效能!

什么是 DevData Talks&#xff1f; DevData Talks 是专注于研发效能实践经验与方法论的系列分享活动。 2022 年&#xff0c;我们既看到外部环境变幻莫测&#xff0c;也看到研发效能领域沉下心来稳步发展&#xff0c;从宏大的概念和价值&#xff0c;转向具体的问题&#xff0c…

若依框架代码自动生成器研究-表查询篇

最近生产环境用了一个开源系统&#xff1a;若依&#xff0c;其中有一个版块很有意思&#xff0c;很能提高生产效率: “代码生成器”。 其功能所处模块菜单为&#xff1a;系统工具->代码生成。我们来研究一下他的代码生成逻辑。 工具使用方法 1、建表 使用代码生成&#…

Python列表中你所不知道的事

1. 引言 目前&#xff0c;Python是世界上使用最广泛、最受欢迎的编程语言之一。Python丰富的功能性使它非常流行&#xff0c;因为我们可以使用它创建任何内容。我将在本博客中与大家分享关于Python列表的几条有趣的花絮。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2.…

如何高薪入职心仪的公司

序 本文首发自&#xff1a;稀土掘金、思否 我们从几个问题开始入手&#xff0c;来看一下本博客是否适合你&#xff1a; 如果你想要换工作&#xff0c;但是&#xff1a;制作的简历平平无奇如果你想要换工作&#xff0c;但是&#xff1a;投放了的简历总是无法得到 [心仪公司] 的…

SpringBoot+Vue茶叶商城系统

简介&#xff1a;本项目采用了基本的SpringBootVue设计的茶叶商城系统。详情请看主要截图。经测试&#xff0c;本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue茶叶商城系统源码作者LHL项目类型Java EE项目 &#xff08;…

C#windows彩票信息管理

摘要&#xff1a;近年来&#xff0c;中国彩票行业已经进入市场急速扩张和加速上升的阶段&#xff0c;即开票占整个彩票销量的比率也将急剧上扬。自助售彩终端&#xff0c;这一崭新的售彩模式已被中国彩民接受&#xff0c;爆发点很快来临。到2020年&#xff0c;我国多功能彩票自…

百趣代谢组学文献分享:OnPLS方法在哮喘领域应用研究

百趣代谢组学文献分享&#xff0c;本周分享的文献题目为OnPLS-Based Multi-Block Data Integration: A Multivariate Approach to Interrogating Biological Interactions in Asthma&#xff0c;是由日本前桥群马大学创新研究中心Craig E. Wheelock教授课题组在2018年发表于Ana…

商业智能 BI 人员的六个Level,你到了哪一层?

现在商业智能 BI 行业的从业人员越来越多&#xff0c;但很多人对于自己的职业规划可能并不是特别的清晰&#xff0c;不知道在这个细分领域到底有多大的成长空间&#xff0c;未来大概可以走到哪一个层次。 今天大概介绍下这六个层次&#xff0c;可以是大多数从事商业智能 BI 工…

【计算机程序设计思想与方法】1 什么是计算?

计算是利用计算机解决问题的过程,计算机科学是关于计算的学问。 计算机科学家在用 计算机解决问题时形成了特有的思维方式和解决方法,即计算思维。 1.1 什么是计算? 1.1.1 计算机与计算 计算机是当代最伟大的发明之一。 自从人类制造出第一台电子数字计算机,迄今已近 …

面试题-Java集合常见问题

1 常见集合集合相关类和接口都在java.util中&#xff0c;主要分为三中List(列表)、Map(映射)和Set(集合)其中Collection是集合List、Set的父接口&#xff0c;它主要有两个子接口&#xff1a;List&#xff1a;存储的元素有序&#xff0c;可重复。ArrayList基于数组实现LinkedLis…

STM32开发(二)CubeMX详解构建基本框架

文章目录STM32 CubeMX背景STM32 CubeMX基本配置选择芯片型号新建工程配置系统时钟、调试口、GPIO配置时钟配置配置GPIO &#xff08;LED为例&#xff09;GENERATE CODE 生成代码使用工具&#xff1a;CubeMX STM32 CubeMX背景 玩过STM32单片机的朋友都知道&#xff0c;以前的时…

网络协议栈简单设计(udp)

网络协议栈简单设计 操作系统内核中实现了网络协议栈&#xff0c;但今天利用netmap&#xff08;也可利用dpdk&#xff09;绕过内核协议栈进行网络数据的收发 netmap 内核协议栈加载数据&#xff1a; 数据从网卡到内核再到内存&#xff0c;需要经过两次拷贝 netmap映射数据&…

List底层源码剖析之List扩容机制

在list集合中有一个add方法&#xff1a; 在众多类中&#xff0c;最长使用的是ArrayList,其中有个方法是add方法 在add方法底层存在 private int size&#xff1b; ensureCapacityInternal(size 1) 其中的size1会对add&#xff08;&#xff09;方法的调用次数进计数&#x…

Docker系列(常用命令) 02

Docker常用命令总结 docker官方命令文档 一、Docker环境信息命令 docker version # 查看docker版本信息 docker info # 查看docker详细信息二、系统日志信息常用命令 2.1 docker events 作用&#xff1a;从服务器获取实时事件&#xff0c;比如&#xff1a;启动、关闭和创…

九龙证券|美国散户疯狂抄底,嗅到了什么?华尔街最新警告

当地时间周五&#xff0c;美股三大指数低开后经历“过山车”行情&#xff0c;虽然盘中一度转涨&#xff0c;但午后再度回落。截至收盘&#xff0c;道指跌0.38%&#xff0c;报收33926.01点&#xff1b;纳指跌1.59%&#xff0c;收于12006.95点&#xff1b;标普500指数跌1.04%&…

九龙证券|全市场注册制下 多层次资本市场定位更清晰

全商场施行注册制的启动&#xff0c;让多层次本钱商场各个板块之间的定位愈加明晰。沪深交易所主板将杰出大盘蓝筹定位&#xff0c;各个板块互联互通也在逐渐加强。 分析人士认为&#xff0c;全面施行股票发行注册制是一场触动本钱商场全局的革新。注册制在全商场推广后&#x…

解读测试能力素质模型

软件测试的能力素质模型(Job Model)&#xff0c;是对不同层级测试工程的能力要求进行明确的定义。目的是为了对每位工程师的能力进行科学的评估&#xff0c;然后分配合理的工作&#xff0c;也帮助大家明确职业规划的方向。 淘宝测试工程师的最常用的有4个&#xff0c;分别是&am…

uniapp(一)

一、初识微信小程序1、什么是微信小程序微信小程序简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户扫一扫或搜一下即可打开应用小程序是一种新的开放能力&#xff0c;开发…

【Redis学习笔记】主从复制

读写分离&#xff0c;性能扩展&#xff1b;快速容灾恢复 一主两从 准备一台服务器&#xff0c;启动不同的redis端口&#xff0c;6379、6380、6381 连接redis-cli redis-cli查看主从信息 info replication主机6379 从机6380、6381 设置从机 config set masterauth password -…

【青训营】架构初探

单机架构 单机架构是把所有功能都实现在一个进程里&#xff0c;并且部署在一台机器上。优点是简单&#xff0c;但是缺点在于其能够承载的带宽有限&#xff0c;而且进行运行维护必须关停服务器。模块之间相互影响&#xff0c; 单体架构 单体架构和单机架构最大的不同是单体架构…