python学习笔记-09

news2024/12/23 1:30:04

面向对象编程-中

面向对象三大特征:封装、继承、多态。

封装:把内容封装起来便于后面的使用。对于封装来讲,就是使用__init__方法将内容封装道对象中,然后通过对象直接或者self获取被封装的内容。

继承:子继承父的属性和方法。

多态:所谓多态就是定义时的类型和运行时的类型不一样,同一种行为对于不同的子类对象有不同的行为表现。python不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,“鸭子类型”。

鸭子类型:在程序设计中,鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
鸭子测试:当看到一只鸟走起来像鸭子、游泳像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。

1.析构函数

析构方法:当一个对象被删除或者被销毁时,python解释器也会默认调用一个方法,这个方法为__del__()方法,也成为析构方法。

一般来讲程序执行结束自动调用此方法。

#析构方法
class Animal:
    def __init__(self,name):
        self.name=name
        print('init方法调用,初始化%s对象'%(self.name))
        pass
    def __del__(self):
        print('del方法调用,释放%s内存空间'%(self.name))
        pass
    pass
cat=Animal('猫')
print('=================')
dog=Animal('柯基')
#由此可看,是当函数彻底执行结束后才释放所有内存空间

在这里插入图片描述
除此之外,对象被删除的时候也会调用析构方法。

#析构方法
class Animal:
    def __init__(self,name):
        self.name=name
        print('init方法调用,初始化%s对象'%(self.name))
        pass
    def __del__(self):
        print('del方法调用,释放%s内存空间'%(self.name))
        pass
    pass
cat=Animal('猫')
del cat   #手动删除对象,执行__del__方法
print('=================')
dog=Animal('柯基')

在这里插入图片描述
析构方法主要是用于释放空间,释放后对象就不能再使用。

总结:
当整个程序脚本执行完毕后会自动调用__del__方法
当对象被手动销毁时也会自动调用__del__方法
析构函数一般用于资源回收,利用__del__方法销毁对象回收内存等资源

2.继承

2.1 单继承

#单继承
#父类:
class Animal:
    def eat(self):
        '''
        父类方法
        :return:
        '''
        print('吃')
        pass
    def drink(self):
        '''
        父类方法
        :return:
        '''
        print('喝')
        pass
    pass
#子类
class Dog(Animal):   #继承Animal
    def wwj(self):
        '''
        子类独有的方法
        :return:
        '''
        print('小狗汪汪叫')
    pass
class Cat(Animal):
    def mmj(self):
        '''
        子类独有的方法
        :return:
        '''
        print('小猫喵喵叫')
        pass
    pass
d1=Dog()
d1.eat()
c1=Cat()
c1.drink()

在这里插入图片描述

对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法,极大提高效率,精简代码,便于扩展。

单继承的语法:
class 子类名(父类名):
		.......

2.2 多继承
子类可以继承多个父类,同时拥有多个父类的公共方法。

#多继承
#父类1
class God:
    def fly(self):
        print('神都会飞')
        pass
    pass
#父类2
class Monkey:
    def eat(self):
        print('猴子都吃桃子')
        pass
    pass
#子类
class Swk(God,Monkey):   #多继承
    def chan(self):
        print('孙悟空会七十二变')
        pass
    pass
s=Swk()
s.chan()
s.fly()
s.eat()

在这里插入图片描述
当多个父类中存在相同的方法时,一层层向上找,就近原则使用。

class D(object):
    def eat(self):
        print('D.eat')
        pass
    pass
class C(D):
    def eat(self):
        print('C.eat')
        pass
    pass
class B(D):
    pass
class A(B,C):
    pass
a=A()
a.eat()
print(A.__mro__)  #可以显示类的依次继承关系

在这里插入图片描述
2.3 继承的传递
孙-子-父

class Grandfather:
    def eat(self):
        print('爷爷的吃')
        pass
    pass
class Father(Grandfather):
    pass
class Son(Father):
    pass
s=Son()
print(Son.__mro__)
s.eat()  #此方法是从父类的父类继承过来的
#在类的传递过程中,我们把父类称为基类,子类称为派生类,父类的属性喝方法可以一级一级的传到子类,多少级都可以

在这里插入图片描述

3.重写父类方法

所谓重写就是在子类中有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法,实际上也就是上述的“就近原则”,这种重写的方法中父类子类的变量什么的都是不互通的。

但如果一味的重写会使父类继承失去意义,因此如果在子类中重写时可以调用父类方法,提高代码效率。

4.调用父类方法

class Dog:
    def __init__(self,name,color):
        self.name=name
        self.color=color
        pass
    def bark(self):
        print('叫')
        pass
    pass
class keji(Dog):
    def __init__(self,name,color):
        Dog.__init__(self,name,color)   #法一:手动调用调用父类的方法,执行完毕就可以具备name,color这两个实例属性了
        super().__init__(name,color)     #法二:也可以这样调用super是自动找到父类进而调用方法,如果有多个父类会逐一的找直到找到为止
        self.height=20  #如果想要除了父类中的属性之外的属性可以声明
        pass
    def bark(self):
        super().bark()
        print('柯基叫')
        print(self.name)
        pass
    def __str__(self):
        return '{}的颜色是{},它的身高是{}'.format(self.name,self.color,self.height)
    pass
kj=keji('柯基','黄')
kj.bark()
print(kj )

在这里插入图片描述

注:
super()自动调用和手动调用写一个就行

5.多态

要想实现多态必须遵守两个前提:
1.继承:多态必须发生在父类和子类之间
2.重写:子类必须要重写父类的方法
#多态
class Animal:
    def speak(self):
        print('我是')
    pass
class Duck(Animal):
    pass
duck=Duck()
duck.speak()
#多态
class Animal:
    def speak(self):
        print('我是')
    pass
class Duck(Animal):
    def speak(self):
        print('我是一个鸭子')
    pass
duck=Duck()
duck.speak()

在这里插入图片描述
在这里插入图片描述
以上就是一种多态的体现,同样是duck.speak,输出两个不一样的结果。
法一:

#多态
class Animal:
    def speak(self):
        print('我是')
    pass
class Duck(Animal):
    def speak(self):
        print('我是一个鸭子')
    pass
duck=Duck()
duck.speak()
class Dog(Animal):
    def speak(self):
        print('我是一只小狗')
        pass
    pass
dog=Dog()
dog.speak()

法二:

#多态
class Animal:
    def speak(self):
        print('我是')
    pass
class Duck(Animal):
    def speak(self):
        print('我是一个鸭子')
    pass
class Dog(Animal):
    def speak(self):
        print('我是一只小狗')
        pass
    pass
def commonInvoke(obj):
    '''
    统一调用的方法
    :param obj:对象的实例
    :return:
    '''
    obj.speak()
    pass
listObj=[Duck(),Dog()]
for i in listObj:
    '''
    循环调用函数
    '''
    commonInvoke(i)

#用一个函数调用

在这里插入图片描述
以上是多态的第二种体现

多态的优点:
增加程序的灵活性
增加程序的扩展性

6.类属性和实例属性

类属性是类对象所拥有的属性,它被所有类对象的实例对象共有,类对象和实例对象可以访问。

实例属性是实例对象所拥有的属性,只能通过实例对象访问

#类属性
class Student:
    name='黎明'   #类属性
    def __init__(self,age):
        self.age=age   #实例属性
        pass
    pass

lm=Student(18)
print(lm.name)    #通过实例对象访问类属性
print(lm.age)
print('------------')
print(Student.name)    #通过类对象访问name
print(Student.age)     #报错是因为age归实例对象所有,不属于类对象
#只有类属性可以被类对象和实例对象共同访问
#实例属性只能由实例对象访问

在这里插入图片描述
所有的实例对象访问的类属性是一个值,实例属性不同。
实例对象对于类属性只有使用的权力,没有修改的权力。

#类属性
class Student:
    name='黎明'   #类属性
    def __init__(self,age):
        self.age=age   #实例属性
        pass
    pass

lm=Student(18)
print(lm.name)    #通过实例对象访问类属性
lm.name='修改'     #重新声明一个值
print(lm.age)
print(lm.name)    #重新声明后改变了自己
print('------------')
xh=Student(22)
print(xh.name)    #重新声明完后并没有改变
print('----------------')
print(Student.name)    #通过类对象访问name

在这里插入图片描述

#类属性
class Student:
    name='黎明'   #类属性
    def __init__(self,age):
        self.age=age   #实例属性
        pass
    pass
Student.name='change'   #这样可以彻底改变类属性的值
lm=Student(18)
print(lm.name)    #通过实例对象访问类属性   
print(lm.age)
print(lm.name)    #重新声明后改变了自己
print('------------')
xh=Student(22)
print(xh.name)    #重新声明完后并没有改变
print('----------------')
print(Student.name)    #通过类对象访问name

在这里插入图片描述

7. 类方法和静态方法

7.1 类方法
类方法:类对象所拥有的方法,需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,类方法可以通过类对象、实例对象调用。

#类方法
class People:
    country='china'
    @classmethod
    def get_country(cls):
        return cls.country  #访问类属性
        pass
    @classmethod
    def change_country(cls,data):
        cls.country=data   #在类方法中修改类属性的值
        pass
    pass
print(People.get_country()) #通过类对象去引用
p=People()
print(p.get_country())
p.change_country('england')
print(p.get_country())

在这里插入图片描述
7.2 静态方法
类对象所拥有的方法,需要用@staticmethod标识静态方法,静态方法不需要任何参数。

#类方法
class People:
    country='china'
    @classmethod
    def get_country(cls):
        return cls.country  #访问类属性
        pass
    @classmethod
    def change_country(cls,data):
        cls.country=data   #在类方法中修改类属性的值
        pass
    @staticmethod
    def getData():
        return People.country
        pass
    pass
print(People.getData())
p=People()
print(p.getData())  #一般情况下,我们不会通过实例对象访问静态方法
#静态方法的逻辑实现和类、实例对象没什么交互,主要用来存放逻辑性代码,一般不会涉及到类中方法和属性的操作。数据资源能够得到充分利用
# 返回当前的系统时间:
import time
class Time:
    @staticmethod
    def showTime():
        return time.strftime('%H:%M:%S',time.localtime())
    pass
print(Time.showTime())

7.3 区别

1.类方法的第一个参数是类对象cls,通过cls引用的类对象的属性和方法,用装饰器@classmethod修饰
2.实例方法的第一个参数是实例对象self,通过self引用的可能是类属性,也有可能是实例属性,具体问题具体分析,不过存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
3.静态方法中不需要额外定义参数,因此在静态方法中引用类属性的化必须通过类对象引用,必须用@staticmethod修饰。

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

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

相关文章

悬浮翻译app免费怎么操作?看完这篇文章就知道了

#高考结束该出发看世界了# 高考的钟声已落,是时候开启探索世界的旅程了。无论是踏上旅途,观看视频,阅读书籍,还是浏览网页资料,我们都有机会拓宽视野。 然而,语言常常成为我们与世界沟通的障碍。好在&…

具身智能特点及实现路线

多模态——多功能的“小脑” 人类具有眼耳鼻舌身意,说明对于物理世界的充分感知和理解,是意识和智慧的来源。而传统AI更多的是被动观测,主要是“看”(计算机视觉)和“读”(文本NLP)&#xff0c…

Kubernetes容器运行时:Containerd vs Docke

容器化技术笔记 Kubernetes容器运行时:Containerd vs Docke - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this arti…

一文教你在centos 7.9中安装mysql5.7(超级详细)

##red## 🔴 大家好,我是雄雄,欢迎关注微信公众号,雄雄的小课堂。 一、前言 每当新来一个服务器之后,习惯性的都会安装一个宝塔面板,不为别的,就为了装环境方便点儿,比如常用的jdk,m…

C++初学者指南第一步---10.内存(基础)

C初学者指南第一步—10.内存(基础) 文章目录 C初学者指南第一步---10.内存(基础)1.内存模型1.1 纸上谈兵:C的抽象内存模型1.2 实践:内存的实际处理 2. 自动存储3.动态存储:std::vector3.1 动态内…

动态住宅代理IP:多账号矩阵管理的使用

如果您要处理多个在线帐户,选择正确的代理类型对于实现流畅的性能至关重要。但最适合这项工作的代理类型是什么? 为了更好地管理不同平台上的多个账户并优化成本,动态住宅代理IP通常作用在此。 一、什么是轮换代理? 轮换代理充当…

逆旅热闹如花盛放

热闹 未及十五,月亮的清辉已可穿透厚厚的云层铺撒人间。 几颗星星点缀着夜空,偶尔一架飞机闪烁着光芒。 很难得的晴夜。 近两个月以来的雨,像电影上的蒙太奇画帧,一幕接一幕,只是单调的灰色,困乏人心。 …

面试官:用过分布式事务吗?

当下的软件架构中,分布式微服务大行其道。然而,分布式系统的核心挑战之一就是如何保证跨多个服务和数据库的数据一致性,这正是分布式事务要解决的问题。 为啥会有分布式事务问题? 在单体应用中,事务管理相对简单&…

两行css 实现瀑布流

html <ul ><li><a href"" ><img src"05094532gc6w.jpg" alt"111" /><p>传奇</p></a></li><li><a href"" ><img src"05094532gc6w.jpg" alt"111"…

QT-QPainter实现一个动态充电的电池

1、效果 2、核心代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>

10万人寻梦玩具好莱坞 ,一人逆袭年销1.8个亿

文丨王一粟 周效敬 奥特曼、四驱赛车、毛绒玩具......如果有一个地方能实现玩具自由&#xff0c;那一定是广东澄海。 澄海是中国乃至世界的玩具之都&#xff0c;给亿万的孩子甚至长大了的孩子带来无数快乐&#xff0c;堪称玩具好莱坞。 无数的年轻人怀揣着实现财富自由的梦想…

电脑怎么恢复出厂设置?系统还原怎么操作?就看这5个方法!

电脑怎么恢复出厂设置&#xff1f;如果您的电脑出现问题&#xff0c;在电脑上恢复出厂重置非常有用。它基本上可以重置电脑&#xff0c;使其恢复到下线时的状态&#xff0c;给你一个全新的开始。众所周知&#xff0c;我们使用电脑的时间越长&#xff0c;电脑上的文件和程序就会…

win10 安装PowerShell

总结: 直接下一步,下一步… 下载链接 https://download.csdn.net/download/qq_43071699/89462517

增加了redis分布式锁,但是还是生成了重复数据

增加了redis分布式锁&#xff0c;但是还是生成了重复数据 原因 两个线程 第一个线程先获取锁&#xff0c;然后进行新增&#xff0c;此时第二个线程也进入方法体&#xff0c;尝试获取锁&#xff0c;结果没获取到&#xff0c;继续在5s内尝试&#xff0c;在redis获取锁等待5s的过…

React+TS 从零开始教程(1)

源码链接&#xff1a;https://pan.quark.cn/s/c6fbc31dcb02 创建项目 直接通过以下命令&#xff0c;我们来创建一个reactts的项目。 npx create-react-app myapp --template typescript这样就创建好了,然后我们导入vscode. npx是npm里面的一个库&#xff0c;可以让你自动使用…

嵌入式linux系统中UART子系统基本实现

今天主要给大家分享一下,如何使用linux系统中的UART帧结构。 第一:UART串口波形 先观察UART波形,是如何被准确识别成字符D,而不是其他的内容呢? 当两个设备需要通过UART协议进行通讯时,它们需要同时约定好以下内容: 每—位信号的时间长度T(波特率= 1/T) 帧结构中每—…

Faiss:选择合适的索引Index

向量相似性搜索彻底改变了搜索领域。它允许我们高效地检索从GIF到文章等各种媒体&#xff0c;即使在处理十亿级别数据集时&#xff0c;也能在亚秒级时间内提供令人印象深刻的准确性。 然而&#xff0c;这种灵活性也带来了一个问题&#xff1a;如何知道哪种索引大小最适合我们的…

118 杨辉三角

题目 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 解析 就是模拟法&#xff0c;没有什么特殊的…

房地产市场的三个背离 欧美市场混动占优,丰田押注小发动机

当前我国房地产市场二手房表现与新房表现明显背离&#xff0c;核心城市表现与低线城市开始背离&#xff0c;未来可能出现房价表现与开发投资景气表现背离。看好核心城市在政策推动下进一步释放需求推动市场结构性复苏的前景。 房地产开发景气度继续下行 2024年5月&#xff0c;…

【人工智能】—基于K-Means算法商场顾客聚类实战教程

在这篇博文之前一直是给大家做机器学习有监督学习教程&#xff0c;今天来一篇无监督学习教程。 K-Means算法是一种基于中心的聚类方法&#xff0c;它试图找到数据点的K个簇&#xff0c;使得簇内的数据点尽可能相似&#xff0c;而簇间的数据点尽可能不同。下面是K-Means算法的详…