07. 面向对象编程(一)

目录

1、前言

2、类和对象

2.1、定义类

2.2、定义方法

2.3、创建对象

2.4、访问控制

2.4.1、公共变量

2.4.2、私有变量

2.4.3、保护成员

2.4.4、总结

3、封装

4、继承

5、多态

6、小结


1、前言

在Python中,面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计范式,它通过创建类(Class)和对象(Object)来组织代码。而面向对象编程有几个基本的特性:封装,继承,多态。

2、类和对象

前言中提到了面向对象编程是通过类和对象来组织代码,那么肯定要先来了解下这两个最重要的概念,类和对象。

  • 类,是一种用于创建对象的蓝图或抽象的模板。比如Animal类,Car类等。
  • 对象,根据抽象模板创建出来的具体的对象(或称该对象是类的实例),每个对象都拥有相同的方法,但各自数据可能不同。比如根据Animal类创建的对象有cat,dog等。

2.1、定义类

要定义一个类,使用关键字class,后跟类的名称。类中通常包含属性(变量)和方法(函数)。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = foot

通过class关键字定义了动物类Animal,同时绑定了2个基本属性name和foot。此后通过该类创建的对象,都必须强制传入这两个属性。类中定义的__init__方法是该类的构造方法,也就是构造该实例的时候需要传入name和foot两个属性共同创建该对象。

注:__init__ 前后是两个_

2.2、定义方法

定义完类之后,我们需要给当前类定义一个方法。面向对象前面提到了其中有一个特性便是封装,而定义的方法便是要对我们的变量数据进行封装。我们在类中定义的name和foot属性,只有在Animal类内部才能访问,其他类是访问不到的。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footdef eat(self):print(f"{self.name} is eating {self.foot}")

与普通方法相比,类中定义的方法第一个参数永远是self,表示当前自身的实例。但是在调用的时候,与普通函数调用一样,不需要传入self变量。上述示例中定义了动物类的吃饭的方法。

这样从外部看Animal类,就只需要知道,创建实例需要给出name和foot,而如何打印,都是在Animal类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。

2.3、创建对象

定义完类和方法之后,我们需要创建该类的实例对象。

# 创建猫和狗的对象
cat = Animal("cat", "fish")
dog = Animal("dog", "bone")# 调用方法
cat.eat()
dog.eat()

结果打印:

2.4、访问控制

在Python中,类的访问控制是通过属性和方法的命名规约来实现的,与Java不同,它并不是通过严格的访问修饰符。

2.4.1、公共变量

公有成员在类的内外部都可以访问。默认情况下,类的属性和方法都是公有的。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footdef eat(self):print(f"{self.name} is eating {self.foot}")cat = Animal("cat", "fish")
dog = Animal("dog", "bone")
print(cat.name)  # name为公共变量,在类外部可以访问

2.4.2、私有变量

私有在类变量的外部是不可访问的,只能在类的内部访问。在Python中,可以通过在属性或方法名称前面添加两个下划线(如__money)来定义私有成员。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footself.__money = 500  # 存款金额,动物怎么会有存款金额,不告诉你def eat(self):print(f"{self.name} is eating {self.foot}")cat = Animal("cat", "fish")
dog = Animal("dog", "bone")
print(cat.name)  # name为公共变量,在类外部可以访问

运行结果:

虽然直接访问私有变量无法访问,但是可以通过定义类方法进行访问。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footself.__money = 500  # 存款金额,动物怎么会有存款金额,不告诉你def eat(self):print(f"{self.name} is eating {self.foot}")def getMoney(self):return self.__moneycat = Animal("cat", "fish")
dog = Animal("dog", "bone")
print(cat.name)  # name为公共变量,在类外部可以访问
# print(cat.__money)  # __money为私有变量,在类外部无法访问
print(cat.getMoney())  # __money为私有变量,但是可以通过定义类方法访问

运行结果:

2.4.3、保护成员

保护成员在命名时,通常使用单下划线作为前缀(如_age)。虽然在语法上是可以访问的,但也建议通过公有方法进行访问。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footself.__money = 500  # 存款金额,动物怎么会有存款金额,不告诉你self._age = 30  # 年龄,虽然动物的年龄不是很私密,但是直接问年龄毕竟不太好def eat(self):print(f"{self.name} is eating {self.foot}")def getMoney(self):return self.__moneycat = Animal("cat", "fish")
dog = Animal("dog", "bone")
# print(cat.name)  # name为公共变量,在类外部可以访问
# print(cat.__money)  # __money为私有变量,在类外部无法访问
# print(cat.getMoney())  # __money为私有变量,但是可以通过定义类方法访问
print(cat._age)

运行结果:

但是PyCharm上是会提示你正在访问的_age是受保护的变量,不推荐直接访问。

我们可以使用类方法进行访问:

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footself.__money = 500  # 存款金额,动物怎么会有存款金额,不告诉你self._age = 30  # 年龄,虽然动物的年龄不是很私密,但是直接问年龄毕竟不太好def eat(self):print(f"{self.name} is eating {self.foot}")def getMoney(self):return self.__moneydef getAge(self):return self._agecat = Animal("cat", "fish")
dog = Animal("dog", "bone")
# print(cat.name)  # name为公共变量,在类外部可以访问
# print(cat.__money)  # __money为私有变量,在类外部无法访问
# print(cat.getMoney())  # __money为私有变量,但是可以通过定义类方法访问
print(cat._age)
print(cat.getAge())

运行结果:

2.4.4、总结

  1. 公开变量(public)。普通变量,普通命名,如name和foot。所有类都可以访问。
  2. 私有变量(private)。内部变量,双下划线(__xxx)命名,如__money。只有类内部才可以访问,类外部无法访问。
  3. 受保护变量(protected)。单下划线(_xxx)命名,如_age。虽然在语法上是可以访问的,但也建议通过公有方法进行访问。
  4. 特殊变量。此外还有一种特殊命名方式,前后都是双下划线(__xxx__),如前面提到的__init__方法。这种变量是可以直接访问的,并不是私有变量。这些命名约定通常具有特殊的含义,用于表示特殊用途的属性或方法。以下是一些常见的双下划线名称:
    • __init__。:用于在创建对象时进行初始化操作,是构造方法。
    • __del__。用于在对象被销毁(垃圾回收)前进行清理操作。
    • __str__。用于定义对象的字符串表示,通过str(obj)调用。
    • __repr__。用于定义对象的“官方”字符串表示,通过repr(obj)调用。

这些命名规范并不是强制性的,而是一种约定俗成的做法。通过这些规范,其他开发者可以更容易地理解你的代码,并且遵循这些规范有助于提高代码的可维护性。同时,使用文档来描述类的成员和其用途也是非常重要的。

3、封装

前面介绍了类和对象后,继续来介绍面向对象的几大特性。首先就是封装。封装是一种将数据和操作封装在类中的机制,通过定义公共接口,隐藏内部实现的细节。在Python中,可以使用私有变量(以双下划线开头)来实现封装。

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footdef eat(self):return f"{self.name} is eating {self.foot}"cat = Animal("cat", "fish")
dog = Animal("dog", "bone")
print(cat.eat())
print(dog.eat())

4、继承

继承是一种允许一个类(子类)继承另一个类(父类)的属性和方法的机制。子类可以重用父类的代码,并且可以添加或修改功能。当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。比如上面定义的Animal类中,有一个call()方法,表示动物的叫声。

Python中继承的语法为:class 子类(继承的父类)。如:

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footdef call(self):return "哈哈哈"   # 父类默认的动物叫声,哈哈哈。应该不可能# Dog类继承了animal,重写了叫声为汪汪汪
class Dog(Animal):def call(self):return f"{self.name} eating {self.foot} and call 汪汪汪"    # 不对,小狗的叫声应该为汪汪汪dog = Dog("dog", "bone")
print(dog.call())

其中Dog继承了Animal,Dog为子类,Animal为父类。Dog重写了父类Animal中的call方法。我们根据Dog类创建出来的实例,调用的call方法,优先调用子类方法。

运行结果:

从中也可以看出,子类继承父类后,也可以直接调用父类的属性变量,如name和foot。那么来试下私有变量和保护变量是否可以访问:

class Animal:def __init__(self, name, foot):self.name = nameself.foot = footself.__money = 500self._age = 30def call(self):return "哈哈哈"   # 父类默认的动物叫声,哈哈哈。应该不可能# Dog类继承了animal,重写了叫声为汪汪汪
class Dog(Animal):def call(self):# return f"{self.name} eating {self.foot} and call 汪汪汪"  # 不对,小狗的叫声应该为汪汪汪return f"[{self._age}]岁的[{self.name}]吃着[{self.foot}], 开心的汪汪汪"    # 不对,小狗的叫声应该为汪汪汪# return f"[{self._age}]岁的[{self.name}]吃着[{self.foot}],数着老爹的[{self.__money}]存款,开心的汪汪汪"    # 不对,小狗的叫声应该为汪汪汪dog = Dog("dog", "bone")
print(dog.call())

没错,私有变量一样访问不了。

此外,继承可以多级下来,爷爷->爸爸->儿子->孙子......。而这些类,追溯到底,都是继承了python的object类。我们平时写的class Animal其实应该是class Animal(object),只是默认这个都会省略掉。

class Animal(object):pass

5、多态

其实多态往往是跟随着继承而得到的好处。多态允许使用相同的接口(方法名)来处理不同类型的对象,即不同的类可以对相同的方法名做出相应。

class Animal(object):pass# Dog类继承了animal,重写了叫声为汪汪汪
class Dog(Animal):def call(self):return "小狗叫声:汪汪汪"  # 不对,小狗的叫声应该为汪汪汪class Cat(Animal):def call(self):return "小猫叫声:喵喵喵"class Dark(Animal):def call(self):return "小鸭叫声:嘎嘎嘎"def call(animal):return animal.call()dog = Dog()
cat = Cat()
dark = Dark()
print(call(dog))
print(call(cat))
print(call(dark))

你会发现,新增一个Animal的子类,不必对call()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。多态的好处就是,当我们需要传入Dog、Cat……时,我们只需要接收Animal类型就可以了,因为Dog、Cat……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有call()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的call()方法,这就是多态的意思。

多条可以让调用方无需关注细节,只需关注调用即可。而这也就是传说中的“开闭”原则。

6、小结

面向对象编程是如今最重要的一种编程模式,也是python中很重要的一个章节。牢记面向对象的几个重要概念:类,对象,属性方法,封装,继承,多态。

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

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

相关文章

vuex的初步使用-1

1. 介绍 Vuex 是一个 Vue 的 状态管理工具,状态就是数据。 简单讲:Vuex 就是一个插件,可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。相对于一个仓库:存放组件共享的数据。 2. 安装 vuex 安装vuex与vue-router类似&…

基于Mapbox的Mvt矢量瓦片集成实践

目录 前言 一、数据说明 1、基本数据 2、属性数据 二、Mapbox集成Mvt矢量瓦片 1、关于访问令牌 2、定义html 3、初始地图 4、加载矢量瓦片 5、效果展示 总结 前言 熟悉矢量瓦片的朋友一定知道,在Webgis当中,矢量瓦片的格式除了pbf的格式&#x…

docker:环境安装

系列文章目录 docker:环境安装 文章目录 系列文章目录前言一、Debian安装1.镜像下载2.VM安装3.Debian安装 二、docker安装1.Debian12换源2.docker安装3.docker测试4.docker换源 总结 前言 因为CentOS7确定停服时间为6月30日,虽然对我这种小虾米没啥影响…

dubbox框架

1、dubbox介绍 Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个基于Java的高性能RPC(Remote Procedure Call)框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。后期阿里巴巴停止了该项目…

HashMap集合万字源码详解(面试常考)

文章目录 HashMap集合1.散列2.hashMap结构3.继承关系4.成员变量5.构造方法6.成员方法6.1增加方法6.2将链表转换为红黑树的treeifyBin方法6.3扩容方法_resize6.3.1扩容机制6.3.2源码resize方法的解读 6.4 删除方法(remove)6.5查找元素方法(get)6.6遍历HashMap集合几种方式 7.初始…

vue安装组件报错In most cases you are behind a proxy or have bad network settings.

解决办法 步骤1 npm config get proxy npm config get https-proxy 如果2个返回值不为null,请执行下面代码,重置为null。否则,直接执行步骤2。 npm config set proxy null npm config set https-proxy null 步骤2 npm config set regis…

cv 不能正常读取中文路径

之前一直以为是PyQT的getOpenFileNames方法不能读取中文路径的。多次尝试后发现不是,是OpenCV的问题。 self.selected_imgPaths, _ QtWidgets.QFileDialog.getOpenFileNames(self, "打开图片", "./pending_images", "*.jpg;;*.JPG;;*.png…

【Windows取证篇】Window日志分析基础知识(一)

【Windows取证篇】Window日志分析基础知识(一) Windows系统审计是对系统中有关安全的活动进行记录、检查以及审核,一般是一个独立的过程。Window自带的事件查看器并没有提供删除特定日志的功能,我们在系统审计取证分析时&#xf…

基于Java+SSM志愿者服务管理系统详细设计和实现【附源码】

基于JavaSSM志愿者服务管理系统详细设计和实现【附源码】 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系…

九、Qt C++ 数据库开发

《一、QT的前世今生》 《二、QT下载、安装及问题解决(windows系统)》《三、Qt Creator使用》 ​​​ 《四、Qt 的第一个demo-CSDN博客》 《五、带登录窗体的demo》 《六、新建窗体时,几种窗体的区别》 《七、Qt 信号和槽》 《八、Qt C 毕业设计》 《九、Qt …

Vue-23、Vue收集表单数据

1、效果 2、代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>收集表单数据</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js…

服务网关 Gateway

服务网关 Gateway Spring Cloud Gateway 是 Spring Cloud 生态系统中的网关&#xff0c;它基于 Spring5.0 SpringBoot2.0 WebFlux&#xff08;基于高性能的 Reactor 模式响应式通信框架 Netty&#xff0c;异步非阻塞模型&#xff09;等技术开发。旨在为微服务架构提供一种简…

Ubuntu系统使用快速入门实践(八)——出现的各种问题

Ubuntu系统使用快速入门实践系列文章 下面是Ubuntu系统使用系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 Ubuntu系统使用快速入门实践系列文章总链接 下面是专栏地址&#xff1a; Ubuntu系统使用快速入门实践系列文章专栏 文章目录 Ubuntu系统使用快速…

Eclipse搭建python环境

一、下载eclipse eclipse官网下载参考链接 二、 下载PyDev ​PyDev 三、安装和配置pyDev 下载完PyDev&#xff0c;解压之后是下面两个文件夹&#xff0c;我下载的版本是PyDev 7.7 ,然后拷到eclipse对应的目录下就可以 四、然后新建一个python程序 1.新建一个项目 ​​…

【C语言】数据结构——排序三(归并与计数排序)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——数据结构学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;1. 归并排序1.1 基本思想1.2 递归实现1.3 非递归实现 2. 计数排序2.1 基本思想2.2 代码实现 导读&#x…

VSCODE上使用IDEA上的快捷键:IntelliJ IDEA Keybindings

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

git项目管理

Git工作流程图 git 基础指令 git init #创建本地仓库,创建成功后&#xff0c;当前目录会多一个.git文件夹 git status #查看修改状态 git add . #添加工作区到暂存区 git commit -m 注释内容 #提交暂存区到本地仓库&#xff08;commit&#xff09; git log …

k8s集群环境搭建以及插件安装

前置条件 终端工具MobaXterm很好用。 1、虚拟机三台&#xff08;ip按自己的网络环境相应配置&#xff09;(master/node) 节点ipk8s-master192.168.200.150k8s-node1192.168.200.151k8s-node2192.168.200.152 2、关闭防火墙(master/node) systemctl stop firewalld systemc…

导游翻译的职责是什么?如何做好导游翻译?

作为旅游行业的关键人物&#xff0c;导游翻译是连接游客与目的地文化的桥梁。他们不仅要具备出色的语言能力&#xff0c;还要深入了解目的地的历史、文化和风俗习惯&#xff0c;为游客提供专业、贴心的导游翻译服务。那么&#xff0c;导游翻译的主要职责是什么&#xff1f;如何…

idea中设置控制台显示service窗口项

一 操作配置 1.1 具体操作 1.操作 2.操作 3.选择应用类型&#xff1a; appplication&#xff0c;springbootapplication等