Python面向对象浅析

news2024/11/28 16:42:10

目录

面向对象基本概念

一、类和对象

类和对象是面向对象骗程的两个核心概念。

在程序开发中,要设计一个类,通常需要满足一下三个要素:

self详解:

对象(Object)

魔法方法:

类里的一些特殊方法

__init__和__del__方法:

repr__和__str

运算符的相关魔法方法:

__eq__方法

类属性和对象属性

简单理解:类属性是整个类共有的属性,对象属性是每个对象实例的属性,类属性的值每个对象都一样,而对象属性的值每个对象各不相同。

私有属性和方法

获取私有属性的方法:

静态方法和类方法:

静态方法和类方法均可通过实例和类调用

单例模式

二、封装(Encapsulation)

三、继承(Inheritance)

父类中的私有方法和私有属性

四、多态(Polymorphism)

五、总结


面向对象基本概念

在编程领域,面向对象编程(OOP)是一种广泛使用的编程范式,它通过创建对象来模拟现实世界中的实体及其交互。Python作为一种高级编程语言,内置了对面向对象编程的全面支持,使得开发者能够轻松构建复杂且易于维护的应用程序。本文将详细探讨Python中的面向对象编程,包括类、对象、封装、继承和多态等核心概念。

一、类和对象

类和对象是面向对象骗程的两个核心概念。

类(Class)
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用.

类是创建对象的蓝图或模板,它定义了对象所具有的属性和方法。属性是对象的特征(如颜色、大小),而方法是对象能够执行的操作(如走、跑、叫)。

在程序开发中,要设计一个类,通常需要满足一下三个要素:

  • 1.类名:这类事物的名字,按照大驼峰命名法(每个单词的首字母大写)起名。
  • 2.属性:这类事物具有什么样的特征。
  • 3.方法:这类事物具有什么样的行为。
class Dog:  
    def __init__(self, name, age):  
        self.name = name  # 实例变量  
        self.age = age  
  
    def bark(self):  
        print(f"{self.name} is barking.")

在这个例子中,Dog是一个类,它有两个实例变量nameage,以及一个方法bark__init__方法是一个特殊的方法,被称为类的构造函数或初始化方法,当创建类的新实例时自动调用。

self详解:

哪个对象调用了方法,方法里的self 指的就是谁。通过self.属性名可以访问到这个对象的属性;通过self.方法名()可以调用这个对象的方法。

 代码举例:

class Student(object):#这里的object表示Student继承自object类
    def __init__(self,x,y):
        self.name=x
        self.age=y
    def say_hello(self):
        print('大家好,我是',self.name)
#Student('张三',18)这段代码具体做了什么呢?
#1.调用__new__方法,用来申请内存空间
#2.调用__init__方法传入参数,将self指向创建好的内存空间,填充数据
#3.变量s1也指向创建好的内存空间
s1=Student('张三',18)
s1.say_hello()
s2=Student('李四',18)
s2.say_hello()

 结果:

大家好,我是 张三
大家好,我是 李四

对象(Object)

对象是类的实例。通过类可以创建多个具有相同属性和方法的对象,但每个对象的属性值可能不同。

d1 = Dog("Buddy", 3)  
d2 = Dog("Max", 5)  
  
d1.bark()  # 输出: Buddy is barking.  
d2.bark()  # 输出: Max is barking.

魔法方法:

类里的一些特殊方法

 # 特点:
#1.不需要手动调用,会在合适的时机自动调用

#2、这些方法,都是使用开始,使用结束#3.方法名都是系统规定好的,在合适的时机自己调用

__init__和__del__方法:

__init__创建对象时会自动调用
__del__当对象被销毁时,会自动调用这个方法

class Person(object):
    def __init__(self,name,age):
        #在创建对象时,会自动调用这个方法
        print('__init__方法被调用了')
        self.name=name
        self.age=age
    def __del__(self):
        #当对象被销毁时会自动调用这个方法
        print('__del__方法被调用了')
p=Person('张三',18)
del p

结果:

 __init__方法被调用了
__del__方法被调用了

repr__和__str

当打印一个对象时,会调用这个对象的__repr__或__str__方法,如果两个方法都写了则调用__str__方法
调用repr()方法,会调用对象的__repr__方法

class Person(object):
    def __init__(self,name,age):
        #在创建对象时,会自动调用这个方法
        print('__init__方法被调用了')
        self.name=name
        self.age=age
    def __del__(self):
        #当对象被销毁时会自动调用这个方法
        print('__del__方法被调用了')
    def __repr__(self):
        return 'repr'+self.name+' '+self.age
    def __str__(self):
        return 'str'+self.name+' '+self.age
p=Person('张三','18')
print(p)
print(repr(p))
print(p.__repr__)

结果:

 __init__方法被调用了
__del__方法被调用了
str张三 18
repr张三 18
<bound method Person.__repr__ of repr张三 18>

运算符的相关魔法方法:

__eq__方法

==会调用对象的_eq_方法,获取这个方法的比较结果
__eq___如果不重写,默认比较依然是内存地址

class Person(object):
    def __init__(self,name,age):
        #在创建对象时,会自动调用这个方法
        self.name=name
        self.age=age
    def __eq__(self,other):
        return self.name==other.name and self.age==other.age
p1=Person('张三',18)
p2=Person('张三',18)
# p1和p2是同一个对象吗?
#怎样比较两个对象是否是同一个对象?比较的是内存地址
# is身份运算符可以用来判断两个对象是否是同一个对象
print(p1 is p2)# False
#is 比较两个对象的内存地址
# ==会调用对象的_eq_方法,获取这个方法的比较结果
nums1 = [1,2,3]
nums2 = [1,2,3]
print(nums1 is nums2)# False
print(nums1 == nums2)#True
#p1==p2本质是p1.eq(p2)获取这个方法的返回值
print(p1==p2)#true,因为在Person类中已经写了__eq__方法

 结果:

False
False
True
True

__ne__方法
!=本质是调用__ne__方法或者__eq__方法取反

__gt__方法
> 本质调用_ne__方法

__ge__方法
> =本质调用__ge__方法


__add__方法
+默认调用此方法

__sub__方法
-默认调用此方法


__str__方法
将对象转换为字符串时会调用此方法
打印对象时也会调用,默认是类型+内存地址

 

类属性和对象属性

简单理解:类属性是整个类共有的属性,对象属性是每个对象实例的属性,类属性的值每个对象都一样,而对象属性的值每个对象各不相同。

class Person(object):
    type='人类'
    def __init__(self,name,age):
        #在创建对象时,会自动调用这个方法
        self.name=name
        self.age=age
#每个实例之间的属性没有关联,互不影响
p1=Person('张三',18)
p2=Person('李四',18)
#可以通过实例对象来获取类属性
print(p1.type)
print(p2.type)

p1.type='human'
print(p1.type) #并不会修改类属性,而是给实例对象增加了一个属性

#类属性只能通过类对象来修改,实例对象无法修改类属性
Person.type='monkey'# 修改了类属性

print(p2.type)
print(Person.type)

 结果:

人类
人类
human
monkey
monkey

私有属性和方法

不能够通过对象.属性(方法)的形式直接调用,会报错
以两个下划线开始的变量或方法为私有的

获取私有属性的方法:

  • 1.使用 对象._类名__私有变量名获取(也适用于私有方法)
  • 2.定义get和set方法来获取
  • 3.使用property来获取

 私有方法可以在类中的其他方法中调用:

 def __demo(self):#__开头的方法为私有方法,在外部不能直接调用
        print('我是私有方法')
 def test(self):
        self.__demo()

静态方法和类方法:

静态方法和类方法均可通过实例和类调用

class Person(object):
    type='rich'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    #如果一个方法里没有用到对象属性和类属性则可定义为静态方法
    @staticmethod
    def demo():
        print('hello')
    #类方法有一个参数cls,无需手动传参,指的是类对象,当前类中 cls is Person
    @classmethod
    def test(cls):#
        print(cls.type)
p=Person('张三',18)
#静态方法和类方法均可以通过实例对象和类对象调用
p.demo()
Person.demo()
p.test()
Person.test()

 结果:

hello
hello
rich
rich

单例模式

简单理解为一个类从始至终只有一个实例对象

class Singleton:
    __instance=None
    __is_first=True
    
    @classmethod
    def __new__(cls,*args,**kwargs):
        if cls.__instance is None:
            cls.__instance=object.__new__(cls)
        return cls.__instance
    def __init__(self,a,b):
        if self.__is_first:
            self.a=a
            self.b=b
            self.__is_first=False
s1=Singleton('哈哈','嘿嘿嘿')
s2=Singleton('呵呵','嘻嘻嘻')
print(s1.a)
print(s2.a)

结果:

哈哈
哈哈 

二、封装(Encapsulation)

封装是面向对象编程的核心思想之一,它将对象的属性和方法封装成一个整体,隐藏对象的内部实现细节,只提供有限的对外接口。在Python中,虽然可以直接访问对象的属性,但通常建议通过方法(如gettersetter)来访问和修改属性,以维护封装性。

class Dog:  
    def __init__(self, name, age):  
        self._name = name  # 使用单下划线表示受保护的属性(习惯用法,Python不强制)  
        self._age = age  
  
    def get_name(self):  
        return self._name  
  
    def set_name(self, name):  
        self._name = name  
  
    # ... 其他方法

三、继承(Inheritance)

继承允许我们定义一个类(子类)来继承另一个类(父类)的属性和方法。子类可以拥有父类的所有属性和方法,并且还可以定义自己的属性和方法。

class Animal:  
    def __init__(self, name):  
        self.name = name  
  
    def speak(self):  
        raise NotImplementedError("Subclass must implement abstract method")  
  
class Dog(Animal):  
    def __init__(self, name, age):  
        super().__init__(name)  # 调用父类的__init__方法  
        self.age = age  
  
    def speak(self):  
        return f"{self.name} says Woof!"  
  
# 使用  
d = Dog("Rex", 4)  
print(d.speak())  # 输出: Rex says Woof!

在这个例子中,Dog类继承了Animal类,并实现了speak方法。

多继承举例:
若一个子类继承了多个父类
例:class A(B,C),即A类同时继承了B、C两个父类,则调用子类的某个方法时,先在A类里面找,若A类没有则会去B类方法里面找,若B类里面也没有,继续找B的父类,若B的祖先类里都没有则回去C里面找,C里面没有去C的父类里面找…(广度搜索下深度搜索)

class Animal(object):#Animal继承自object类
    def __init__(self,name,age):
        self.name=name
    def sleep(self):
        print(self.name+'正在睡觉')
class Dog(Animal,object):#Dog类继承自Animal类
    def bark(self):
        print(self.name+'正在叫')
d=Dog('小哈',3)
d.bark()
print(Dog.__mro__)

结果:

 小哈正在叫
(<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>)

父类中的私有方法和私有属性

父类中的私有方法和属性不能继承
可以通过对象名._父类名__私有方法(或属性名进行调用)

class Animal(object):#Animal继承自object类
    def __init__(self,name,age):
        self.name=name
        self.__age=age
    def __sleep(self):
        print(self.name+'正在睡觉')
class Dog(Animal):#Dog类继承自Animal类
    def bark(self):
        print(self.name+'正在叫')
d=Dog('小哈 ',3)
print(d._Animal__age)
d._Animal__sleep()

 结果:

3
小哈 正在睡觉

四、多态(Polymorphism)

多态允许不同类的对象对同一消息作出响应。在Python中,多态是隐式实现的,因为Python是动态类型语言。你可以定义一个接受任意类型对象作为参数的函数,并在这个函数中调用这些对象的方法,而不需要关心它们的具体类型。

def make_it_speak(animal):  
    return animal.speak()  
  
# 假设还有其他类,如Cat,也实现了speak方法  
class Cat(Animal):  
    def speak(self):  
        return f"{self.name} says Meow!"  
  
c = Cat("Whiskers")  
print(make_it_speak(c))  # 输出: Whiskers says Meow!

在这个例子中,make_it_speak函数可以接受任何具有speak方法的对象作为参数,并调用该方法。

五、总结

面向对象编程为Python开发者提供了一种强大而灵活的方式来构建和维护复杂的软件系统。通过类、对象、封装、继承和多态等核心概念,开发者能够创建出高度模块化和可重用的代码,从而提高开发效率和软件质量。希望本文能够帮助到大家更好地理解和应用Python的面向对象编程。
                        
本文灵感来自原文链接:https://blog.csdn.net/m0_46213598/article/details/119256595

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

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

相关文章

RK3568笔记四十八:ADC驱动开发测试

若该文为原创文章&#xff0c;转载请注明原文出处。 一、ADC介绍 RK3568集成了一个逐次逼近模数转换器&#xff08;Successive Approximation ADC&#xff09;&#xff0c;通常简称为SAR ADC。 这种转换器能够将连续的模拟信号转换为离散的数字信号&#xff0c;其特点在于具有…

nginx转发netty长链接(nginx负载tcp长链接配置)

首先要清楚一点&#xff0c;netty是长链接是tcp连接不同于http中负载在http中配置server监听。长连接需要开启nginx的stream模块(和http是并列关系) 安装nginx时注意开启stream&#xff0c;编译时加上参数 --with-stream &#xff08;其他参数根据自己所需来加&#xff09; …

rem实现屏幕适配(jQuery)

一、rem换算 1.根据视口宽度动态计算字体大小&#xff0c;如果宽度大于750px&#xff0c;则将字体大小设置为100px&#xff0c;否则按比例缩小。 tips:使用时记得引入jQuery.js // 在文档加载完成后执行函数&#xff0c;确保DOM已经准备就绪$(function () {// 定义一个自执行…

增量学习中Task incremental、Domain incremental、Class incremental 三种学习模式的概念及代表性数据集?

1 概念 在持续学习领域&#xff0c;Task incremental、Domain incremental、Class incremental 是三种主要的学习模式&#xff0c;它们分别关注不同类型的任务序列和数据分布变化。 1.1 Task Incremental Learning (Task-incremental) 任务增量学习&#xff0c;也称为任务增…

盐分反演关键:批量计算常用的盐分指数反演变量

盐分反演关键&#xff1a;批量计算常用的盐分指数反演变量 一、引言 盐分指数反演是遥感应用中的一个重要方面&#xff0c;尤其在农业和环境监测中有着广泛的应用。通过遥感影像&#xff0c;研究人员可以高效地获取和分析地表盐分信息&#xff0c;为土地管理和作物生产提供重…

YOLOX+PyQt5交通路口智能监测平台设计与实现

1.概述 交通要道的路口上人车穿行&#xff0c;特别是上下班早高峰&#xff0c;且时常发生交通事故。因此对交通路口的车流量和人流量的监测必不可少。 2.检测模型 使用的检测模型为YOLOX模型&#xff0c;模型权重为训练VOC数据集得来&#xff0c;其中包括了二十个类别&#…

ONLYOFFICE 协作空间 2.6 已发布:表单填写房间、LDAP、优化房间和文件管理等

更新后的 ONLYOFFICE 协作空间带来了超过 20 项新功能和优化&#xff0c;让工作更加高效和舒适。阅读本文了解详情。 表单填写房间 这次更新增加了一种新的房间类型&#xff0c;可在 ONLYOFFICE 协作空间中组织简单的表单填写流程。 通过表单填写房间&#xff0c;目前可以完成…

仓库物品与装备物品位置更换

一、装备物品与选中的仓库物品位置交换 1、准备工作 2、Inventory Items 3、给Warehouse添加Grid Layout Group组件 4、复制Inventory Items&#xff0c;设置Grid Layout Group组件 5、创建文本ItemName和ItemDescription 6、设置物品数据 (1) 创建 ItemData.cs using Syst…

Spring boot tomcat 读写超时时间设置

yaml配置 connection-timeout: 20000 server:port: 9898servlet:context-path: /testtomcat:connection-timeout: 20000max-connections: 250accept-count: 300 spring源码设置自定义tomcat参数 customizeConnector(connector); Overridepublic WebServer getWebServer(Serv…

【MySQL】表的约束{ 常见约束 空属性 默认值 列描述comment zerofill 主键 复合主键 自增长 唯一键 外键 }

文章目录 常见约束空属性默认值列描述commentzerofill主键复合主键自增长唯一键外键 2.总结 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。比…

MySQL基础练习题12-使用唯一标识码替换员工ID

题目&#xff1a;展示每位用户的 唯一标识码&#xff08;unique ID &#xff09;&#xff1b;如果某位员工没有唯一标识码&#xff0c;使用 null 填充即可。 准备数据 分析数据 题目&#xff1a;展示每位用户的 唯一标识码&#xff08;unique ID &#xff09;&#xff1b;如果…

一, 创建工程,引入依赖

一&#xff0c; 创建工程&#xff0c;引入依赖 文章目录 一&#xff0c; 创建工程&#xff0c;引入依赖创建工程工程间的关系的建立配置各个工程当中的 pow 配置信息&#xff0c;相关的依赖父工程(也就是总项目工程)的 pow 配置demo-module06-generate 模块中pow 配置&#xff…

基于IEC61499标准的在线工业编程平台open61499

基于IEC61499标准的在线工业编程平台open61499是一个专为工业自动化领域设计的编程环境&#xff0c;它遵循IEC 61499标准&#xff0c;为开发者提供了一种高效、灵活的方式来创建、配置和管理分布式控制系统&#xff08;DCS&#xff09;的应用程序。以下是对open61499的详细解析…

LeetCode热题 翻转二叉树、二叉树最大深度、二叉树中序遍历

目录 一、翻转二叉树 1.1 题目链接 1.2 题目描述 1.3 解题思路 二、二叉树最大深度 2.1 题目链接 2.2 题目描述 2.3 解题思路 三、二叉树中序遍历 3.1 题目链接 3.2 题目描述 3.3 解题思路 一、翻转二叉树 1.1 题目链接 翻转二叉树 1.2 题目描述 1.3 解题思路 根…

【多模态大模型】 BLIP in ICML 2022

一、引言 论文&#xff1a; BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 作者&#xff1a; Salesforce Research 代码&#xff1a; BLIP 特点&#xff1a; 该方法分别使用ViT和BERT进行图像和文本特征提取&am…

【changchain-community安装失败】‘EntryPoints‘ object has no attribute ‘get‘报错解决

在安装changchain-community时报错信息如下&#xff1a; WARNING: Keyring is skipped due to an exception: EntryPoints object has no attribute get ERROR: Could not find a version that satisfies the requirement changchain-community ERROR: No matching distributio…

进程间通信与线程间通信的方法汇总

目录 一、进程间通信机制 管道(pipe)&#xff1a; 命名管道(FIFO)&#xff1a; 消息队列(MQ)&#xff1a; 信号量(semaphore)&#xff1a; 共享内存(shared memory)&#xff1a; 信号(signal)&#xff1a; 内存映射(mapped memory)&#xff1a; 内存映射和共享内存的区…

华杉研发九学习日记20 LinkedHashMap TreeMap Arrays 函数式接口 方法引用

华杉研发九学习日记20 一&#xff0c;LinkedHashMap 与HashMap相比&#xff0c;key是有序的 Map<Integer,String> map new LinkedHashMap<Integer,String>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.…

GitHub Desktop commit文件到repository

1. Clone a repository到本地 2. 在本地仓库修改/添加需要提交的文件或者文档 3. 添加comments并commit 4. 提交完成&#xff0c;点击Push origin提交代码到Github远程仓库 上传成功后&#xff0c;刷新Github网站页面就会出现上传的项目

鸿蒙应用框架开发【自绘编辑框】 输入法框架

自绘编辑框 介绍 本示例通过输入法框架实现自会编辑框&#xff0c;可以绑定输入法应用&#xff0c;从输入法应用输入内容&#xff0c;显示和隐藏输入法。 效果预览 使用说明 1.点击编辑框可以绑定并拉起输入法&#xff0c;可以从输入法键盘输入内容到编辑框。 2.可以点击a…