Python编程6——面向对象编程1
1 介绍
面向对象编程(Object Oriented Programming,OOP):是一种解决软件复用的设计和编程方法。这种方法把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的形式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。
面向对象和面向过程的区别:
(1)面向过程:根据业务逻辑从上到下写代码;
(2)面向对象:将数据与函数绑定到一起,分类进行封装,每个程序员只要负责分配给自己的分类,这样能够更快速的开发程序,减少了重复代码。
用面向对象的思维解决问题的重点:
(1)当遇到一个需求的时候不用自己去实现,如果自己一步步实现那就是面向过程
(2)应该找一个专门做这个事的人来做
(3)面向对象是基于面向过程的
2 类和对象
面向对象编程的2个非常重要的概念:类和对象。
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类。
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象。
2.1 类
类的定义:
具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
具有相同属性和行为事物的统称。
类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象。
类(Class) 由3个部分构成:
类的名称:类名(通常首字母大写)
类的属性:一组数据
类的方法:允许对进行操作的方法 (行为)
拥有相同(或者类似)属性和行为的对象都可以抽像出一个类。
提炼类的方法:一般名词都是类(名词提炼法)。
定义类的格式如下:
class 类名:
方法列表
说明:
(1)定义类时有2种:新式类和经典类,上面的Car为经典类,如果是Car(object)则为新式类;
(2)类名 的命名规则按照"大驼峰"。
# 定义类
class Calculator:
name = 'Good calculator'
price = 10
# 方法
def add(self, x, y):
print(x + y)
def minus(self, x, y):
print(x - y)
def times(self, x, y):
print(x*y)
def divide(self, x, y):
print(x/y)
calcul = Calculator()
print('calcul.name = ', calcul.name)
print('calcul.price = ', calcul.price)
calcul.add(1,2)
2.2 对象
定义:某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。
可以是直接使用的。
类和对象的关系:类就是创建对象的模板
创建对象:
python中,可以根据已经定义的类去创建出一个个对象。
创建对象的格式为:
对象名 = 类名()
示例:
# 定义类
class Car:
# 移动
def move(self):
print('车在奔跑...')
# 鸣笛
def toot(self):
print("车在鸣笛...嘟嘟..")
# 创建一个对象,并用变量BMW来保存它的引用
BMW = Car()
BMW.color = '黑色'
BMW.wheelNum = 4 #轮子数量
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)
print(BMW) # 输出BMW对象在内存中的地址
输出结果:
车在奔跑...
车在鸣笛...嘟嘟..
黑色
4
<__main__.Car object at 0x00000226CAD0A880>
注:
第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,如果后面再次出现BMW.color = xxx表示对属性进行修改。
BMW是一个对象,它拥有属性(数据)和方法(函数)。
3 self
示例:
# 定义一个类
class Animal:
# 方法
def __init__(self, name):
self.name = name
def printName(self):
print('名字为:%s'%self.name)
# 定义一个函数
def myPrint(animal):
animal.printName()
dog1 = Animal('西西')
myPrint(dog1)
dog2 = Animal('北北')
myPrint(dog2)
运行结果:
名字为:西西
名字为:北北
总结:
所谓的self,可以理解为自己。
可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思。
某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可。
4 实例方法
4.1 __init__方法
创建对象后,python解释器默认调用__init__()方法;
(1)使用方式
def 类名:
#初始化函数,用来完成一些默认的设定
def __init__():
pass
(2)调用方式
# 定义汽车类
class Car:
def __init__(self, newWheelNum, newColor):
self.wheelNum = newWheelNum
self.color = newColor
def move(self):
print('车在跑,目标:夏威夷')
# 创建对象
BMW = Car(4, 'green')
print('车的颜色为:%s'%BMW.color)
print('车轮子数量为:%d'%BMW.wheelNum)
BMW.move()
__init__()方法总结:
(1)在创建一个对象时默认被调用,不需要手动调用
(2)__init__(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中除了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)
(3)__init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去。
4.2 “魔方”方法
__str__()方法:
class Car:
#定义初始化方法
def __init__(self, newWheelNum, newColor):
self.wheelNum = newWheelNum
self.color = newColor
#定制print时的显示内容
def __str__(self):
msg = "嘿。。。我的颜色是" + self.color + "我有" + str(self.wheelNum) + "个轮胎..."
return msg
def move(self):
print('车在跑,目标:夏威夷')
BMW = Car(4, "白色")
print(BMW)
运行结果:
嘿。。。我的颜色是白色我有4个轮胎...
总结:
(1)在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。
(2)当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据。
4.3 __del__方法
当删除一个对象时,python解释器会默认调用__del__()方法。
import time
class Animal(object):
# 初始化方法
# 创建完对象后会自动被调用
def __init__(self, name):
print('__init__方法被调用')
self.__name = name
# 析构方法
# 当对象被删除时,会自动被调用
def __del__(self):
print("__del__方法被调用")
print("%s对象马上被删除了..."%self.__name)
import time
class Animal(object):
# 初始化方法
# 创建完对象后会自动被调用
def __init__(self, name):
print('__init__方法被调用')
self.__name = name
# 析构方法
# 当对象被删除时,会自动被调用
def __del__(self):
print("__del__方法被调用")
print("%s对象马上被删除了..."%self.__name)
# 创建对象
dog = Animal("大黄毛")
# 删除对象
print("---马上 删除dog对象")
del dog
cat = Animal("波斯猫")
cat2 = cat
print("---马上 删除cat对象")
del cat
print("---马上 删除cat2对象")
del cat2
print("程序2秒钟后结束")
time.sleep(2)
运行结果:
__init__方法被调用
---马上 删除dog对象
__del__方法被调用
大黄毛对象马上被删除了...
__init__方法被调用
---马上 删除cat对象
---马上 删除cat2对象
__del__方法被调用
波斯猫对象马上被删除了...
程序2秒钟后结束
总结:
(1)当有1个变量保存了对象的引用时,此对象的引用计数就会加1;
(2)当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除。即只有对象的引用计数为0时,对象才会被真的删除。
5 保护对象的属性-私有属性
如果有一个对象,当需要对其进行查看或修改属性时,有2种方法:
(1)对象名.属性名 = 数据 ---->直接修改
(2)对象名.方法名() ---->间接修改
分析:
为什么推荐定义方法来间接修改呢?
至少有2个原因:
(1)如果直接修改属性,烤地瓜至少需要修改2部分,即修改cookedLevel和cookedString。而使用方法来修改时,只需要调用一次即可完成。
(2)如果直接访问属性,可能会出现一些数据设置错误的情况产生例如cookedLevel = -3。这会使地瓜比以前还生,当然了这也没有任何意义,通过使用方法来进行修改,就可以在方法中进行数据合法性的检查。
如果一个对象与另外一个对象有一定的关系,那么一个对象可能是另外一个对象的属性。
为了更好的保存属性安全,即不能随意修改,一般的处理方式为:
(1)将属性定义为私有属性;
(2)添加一个可以调用的方法,供调用。
class People(object):
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
def setName(self, newName):
if len(newName) >= 2:
self.__name = newName
else:
print("error:名字长度需要大于或者等于5")
tangseng = People("陈玄奘")
print(tangseng.getName())
tangseng.setName("唐三藏")
print(tangseng.getName())
总结:
(1)Python中没有像C++中public和private这些关键字来区别公有属性和私有属性。
(2)它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。
参考:
Python官方文档:https://docs.python.org/3/library/
https://blog.csdn.net/swan777/article/details/89040802