面向对象基础
闲谈:
Python设计之初是一门面向对象语言,面向对象其实就是一种编程的思想,现在人们比较认可的解释就是:封装、继承、多态即为面向对象。
封装、继承、多态确实是一种面向对象的体现,感觉这种解释比较牵强,面向对象的思想比较抽象,暂时没有更好的解释。
什么是面向对象:
面向对象编程(Object Oriented Programming)简称OOP:(解释非官方)将某一类具体的事物抽象出来其特征,行为,分析、设计和实现一个完整的程序。
面向对象思想的实现流程:
面向对象的分析(OOA, Object-Oriented Analysis)
面向对象的设计(OOD, Object-Oriented Design)
面向对象的程序设计(OOP, Object-Oriented Program)
面向对象测试(OOT,Object-Oriented Test)
面向对象维护(OOSM,Object-Oriendted Soft Maintenance)
程序员认为一切皆为对象,都可以代码化。了解过程序常识的人都知道,程序员总是说没有对象怎么办?没有对象new一个!!这其实是Java语言中实例化对象的一个梗,Python被人称为最优美、最简洁的语言,实例化对象以及类的定义确实比Java简单一点。
今天咱要要说一说Python语言的类(Class),话不多说,举个例子:现在我要统计我认识的人都用的什么手机,什么品牌,多大内存...等等,傻傻的就有人开始了,他的代码是这样的:
代码语言:javascript复制xxx_phone_name = 'iphone11'
xxx_phone_screen_size = '6.1英寸'
xxx_phone_color = '黑色'
xxx_phone_ram = '3GB'
xxx_phone_rom = '128GB'
xxx_phone_camera = '1200万'
xxx_phone_battery = '3200mAh'
xxx_phone_price = 5499
xxx_phone_use = '打游戏'
# ...
这统计一个都麻烦的要死,统计百八十个都累吐血了,所以咱们接下来认识一下类。
类:
一种复杂的自定义数据类型,参数可以是任何数据类型。
类的定义格式:
代码语言:javascript复制class <类名>(父类列表):
类变量...
初始化方法(self, 对象的变量...)
类方法
静态方法
属性
成员方法/对象方法
析构方法
以上的具体内容后面会慢慢介绍,首先咱们先用面向对象的方法分析一下。目前我们的需求是统计某个人使用的手机品牌,屏幕大小,什么颜色,运行内存大小,存储大小,像素,电池大小,价格,以及这个人主要用来做什么。所以我们规定手机这个对象必须有这些参数,用类的方法写出来的程序就是这样的:
代码语言:javascript复制class Phone:
def __init__(self, name, screen_size, color, ram, rom, camera, battery, price, use):
self.name = name
self.screen_size = screen_size
self.color = color
self.ram = ram
self.rom = rom
self.camera = camera
self.battery = battery
self.price = price
self.use = use
def do(self):
print('经常使用手机' self.use)
xxx_phone = Phone('iphone11', '6.1英寸', '黑色', '3GB',
'128GB', '1200万', '3200mAh', 5499, '打游戏')
print('品牌:{},屏幕大小:{},颜色:{},运行内存:{},机身存储:{},像素:{},电池容量:{},价格:{}'.format(xxx_phone.name,
xxx_phone.screen_size, xxx_phone.color, xxx_phone.ram, xxx_phone.rom, xxx_phone.camera, xxx_phone.battery, xxx_phone.price))
xxx_phone.do()
运行结果如下:
代码语言:javascript复制品牌:iphone11,屏幕大小:6.1英寸,颜色:黑色,运行内存:3GB,机身存储:128GB,像素:1200万,电池容量:3200mAh,价格:5499
经常使用手机打游戏
虽然现在看起来代码比之前多了,但是想想上万条数据的话哪个更方便呢?
注意事项:
1、类名首字母大写,为了与文件名(模块名),函数名等区分,这是个规范(非规定)
2、一定要初始化函数
3、初始化函数的第一个参数self可以更改,不过不推荐更改,Python语言就是用的self,谁实例化self表示谁,用于区分同名的成员变量与对象变量。
程序的基本运行流程:
对象的构造过程:
1、为对象开辟空间,使用new构造方法2、调用初始化方法init初始化3、返回对象的引用。
代码语言:javascript复制class Phone:
def __new__(cls,*args,**kwagrs):
print('我先执行,开辟内存空间')
# 返回并调用父类new构造方法,object为所有类的父类
return object.__new__(cls)
def __init__(self,name):
self.name = name
print('实例化对象')
# 析构函数,对象销毁前执行,一般忽略
def __del__(self):
print('对象被销毁前执行我')
phone1 = Phone('iphone 11')
phone2 = Phone('iphone x')
phone3 = Phone('iphone 8')
phone4 = Phone('iphone 7')
phone4 = Phone('iphone 11')
print(phone1.name)
print(phone2.name)
print(phone3.name)
print(phone4.name)
结果如下:
代码语言:javascript复制我先执行,开辟内存空间
实例化对象
我先执行,开辟内存空间
实例化对象
我先执行,开辟内存空间
实例化对象
我先执行,开辟内存空间
实例化对象
我先执行,开辟内存空间
实例化对象
对象被销毁前执行我
iphone 11
iphone x
iphone 8
iphone 11
对象被销毁前执行我
对象被销毁前执行我
对象被销毁前执行我
对象被销毁前执行我
phone4变量先指向Phone('iphone 7')对象,后指向Phone('iphone 11'),因此Phone('iphone 7')对象先销毁,可理解为后面的对象覆盖的前面的对象,前面的对象没用就销毁了,程序结束前销毁的所有对象。
垃圾回收机制:(简单说一下)
程序中的对象有垃圾回收器(garbage collector)负责释放,回收之前会自动调用对象对应类的析构方法,做释放前的准备工作(关闭占用资源等)。
回收机制:
1、引用计数
2、标记清除
3、分代回收
系统为每个类自动提供一个默认的无参的初始化方法;
若自定义初始化方法,无参初始化方法不再提供。Java语言必须提供一个无参的构造方法,而Python则不需要,下面两段代码是一样的。
代码语言:javascript复制class Test():
pass
t = Test()
print(t)
class Test1():
def __init__(self):
pass
t1 = Test1()
print(t1)
结果如下:
代码语言:javascript复制<__main__.Test object at 0x000002F57E31A208>
<__main__.Test1 object at 0x000002F57E31ADD8>
打印的为对象的内存地址,如果直接打印实例化对象,想按照自己的格式来打印,则需要重写str方法,如:
代码语言:javascript复制class Phone:
def __init__(self, name):
self.name = name
def __str__(self):
return '手机为:' self.name
phone1 = Phone('苹果')
phone2 = Phone('华为')
print(phone1)
print(phone2)
结果如下:
代码语言:javascript复制手机为:苹果
手机为:华为
类和对象的关系:
1.类是对象的模板
2.一个类可以创建多个对象、
3.对象是类一个特定的个体
4.对象有独立的内存空间,不会互相影响
== 与 is:
== 一般用于比较值
is 用于比较内存地址,查看内存地址id(x)
代码语言:javascript复制class Phone:
def __init__(self, name):
self.name = name
phone1 = Phone('iphone 11')
phone2 = Phone('iphone 11')
print(phone1.name == phone2.name)
print(phone1 == phone2)
print(phone1 is phone2)
结果如下:
代码语言:javascript复制True
False
False
实例化的两个对象虽然看起来一样,但是却不是同一个对象,就像两个一样的手机,在不同人的手机中,自己的手机丢了,不能以为两个手机一样,就说别人的手机就是自己的。
如果有特殊需要,如两个不同的手机对象,只要名称相同就认为相等,就需要重写eq方法。
代码语言:javascript复制class Phone:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
phone1 = Phone('iphone 11')
phone2 = Phone('iphone 11')
print(phone1 == phone2)
结果为:
代码语言:javascript复制True
类属性:
现在回到最开始的例子,统计自己的手机,它们都有一个共同的特征,就是这些手机的拥有者是我们自己。假如我们给每个实例化的手机加一个同样的参数,就有些麻烦,因此介绍以下类属性:所有实例化对象都拥有的属性。
代码语言:javascript复制class Phone:
owner = 'me'
def __init__(self, name):
self.name = name
phone1 = Phone('华为')
phone2 = Phone('荣耀')
print(Phone.owner)
print('这部' phone1.name '手机属于:' phone1.owner)
print('这部' phone2.name '手机属于:' phone2.owner)
代码语言:javascript复制执行结果为:
代码语言:javascript复制me
这部华为手机属于:me
这部荣耀手机属于:me
类属性,类可以直接调用,生成的所有的对象也能调用。
总结
面向对象与面向过程:两种不同的编程思想,面向过程就是按部就班的一步步,有顺序、有步骤的执行。而面向对象是先弄明白需求,设计模板,大批量生产。就像有两个人去收割麦子,面向过程是这样的:
代码语言:javascript复制1、拿上镰刀
2、收割麦子
3、运输回家
4、收割麦子
5、运输回家
6、...
面向过程的思想就是:需求是收割麦子,造一辆收割机,然后可以一直收割麦子。两种思想有不同的使用场景,就像需要收割的麦子只有巴掌大小,和上千亩良田。
这篇文章介绍了面向对象的编程思想,类的简单定义,成员属性以及类属性,希望能给想学Python语言的人带来一点帮助。
------------------- End -------------------