1.面向对象思想
- 面向对象中的对象(Object),通常指客观世界存在对象,对象具有唯一性,对象之间各不相同,各有特点,每个对象有自己的运动规律和内部状态。
- 对象对象之间相互联系,相互作用,对象也可以是一个抽象事物,世间万物皆对象,对象划分两部门,静态部分和动态部分。静态部分称为"属性",任何对象具有自身属性,属性是客观存在,不能被忽视,动态部分值对象的行为,对象执行的动作
2.类和对象
- 类:封装对象属性和行为的载体,相同属性和行为一类实体称为类,用户自定义数据类型,模板,不占用内存
- 对象:类定义的变量,占用内存
类:
成员属性:描述对象的静态特征,如名字、身高体重
成员方法:描述对象的动态特征,例如:吃饭、睡觉、打豆豆
2.1 定义类
Python中类的定义,使用class关键字实现,语法如下:
class ClassName:
'''类的帮助信息''' # 类文档字符串
statement # 类体
- ClassName:类名,大写字母开头,如类名包括两个单词,第二个单词首字母大写"驼峰式命名法",约定俗称惯例,当然可以根子自己习惯命名,推荐惯例命名
- ‘’‘类的帮助信息’’’ :指定类的文档字符串
- statement:类体,由类变量(或类成员)、方法和属性等定义语句组成,定义类时没想好功能可以用pass语句代替
- Python3中类默认继承object,可以这样写class Dog:,等价class Dog(object):
2.2 类的创建
- self参数在调用的时候不必传值,由系统传值
- self只能在实例方法中使用
- 方法的第一个参数self其实可以使用任何合法标识符,不过一般约定俗称都是self
- 方法和函数的区别:
1.方法作用域属于类,所以即便和不同函数重名,也不会被被覆盖
2.方法的第一个参数必须是self,但函数不要求
3.方法必须通过对象调用,而函数不需要
# 定义类
class Dogs: # 等价class Dog(object):
def bark(self): # 成员方法,第一个参数必须时self,代表当前调用对象
print('我是小可爱--丁丁')
dingding = Dogs() # 实例化一个对象
# 调用方法:不需要传参数,self系统传递
# 调用形式:对象.方法([实参])
dingding.bark() # 输出:我是小可爱--丁丁
# 方法连贯调用,方法返回self
class Dog:
def bark(self):
print('汪汪汪')
return self # 返回self
def eat(self):
print('爱啃大骨头')
return self
dog = Dog()
dog.eat().bark()
'''
输出:
爱啃大骨头
汪汪汪
'''
2.3 对象的创建
- 对象创建过程称为对象实例化过程,定义了一个类类型变量或者称为实例(instance)的过程
# 语法: 对象 = 类名([实参])
class Dogs:
def sleep(self):
print('喜欢睡觉')
ding = Dogs() # 实例化一个对象
print(ding) # 输出:<__main__.Dogs object at 0x000001FE30E242B0> 可以看出dings是Dogs类的实例
print(type(ding)) # 输出:<class '__main__.Dogs'>
# 查看对象的类名
print(ding.__class__) # 输出:<class '__main__.Dogs'>
2.4 成员属性
- 成员属性描述是对象静态特征,比如狗名字,品种等,其实是一个变量,作用域属于对象,不会和类外的全局变量冲突。
- Python中成员属性可以在构造函数中添加,成员属性对象,每个对象的成员属性的值都不相同
class Dog:
def __init__(self,name,kind,age):
self.name = name
self.kind = kind
self.age = age
def bark(self):
print('我是小可爱--顶定')
dingding = Dog('丁丁','泰迪','3')
print('我是可爱的{}犬,我叫{},我今年{}岁了'.format(dingding.kind,dingding.name,dingding.age))
'''
输出:我是可爱的泰迪犬,我叫丁丁,我今年3岁了
'''
# 查看实例属性
print(dingding.__dict__) # __dict__属性查看实例属性输出:{'name': '丁丁', 'kind': '泰迪', 'age': '3'}
print(dir(dingding)) # 查看Dog的属性,包括实例属
3.构造和析构
- 构造函数--------------------- init( self )
- 析构函数--------------------- del( self )
3.1 构造方法
- 目的:构造方法用于初始化对象(不创建对象),可以在构造方法中添加成员属性
- 时机:实例化对象的时候自动调用
- 参数:第一个参数必须是self,其它参数根据需要自己定义
- 返回值:不返回值,或者说返回None,不应该返回任何其他值
语法:
def __init__(self,arg1,arg2......):
函数体
# 参数:arg1,arg2...根据需要自己定义
# 如果自己不定义构造方法,系统会自动生成一个构造函数
def __init__(self):
pass
注意:
如果没有定义构造方法,系统会生成一个无参构造方法,如果自己定义了构造方法,则系统不会自动生成
一个类只能有一个构造方法,如果定义多个,后面的会覆盖前面的
构造函数由系统在实例化对象时自动调用,不需要自己调用
class Dog:
def __init__(self,name,king,age):
self.name = name # 定义对象属性,这个类所有的对象都具有该属性
self.kind = king # 成员属性必须通过self.引用,否则是普通的变量
self.age = age
def bark(self):
print('我是小可爱--丁丁')
ding = Dog(name='丁丁',king="泰迪",age="3")
print('我是可爱的%s犬,%s,我今年%s岁了'%(ding.kind,ding.name,ding.age))
'''
输出:我是可爱的泰迪犬,丁丁,我今年3岁了
'''
3.2 析构方法
- 目的:对象销毁时,释放资源
- 时机:对象销毁时由系统自动调用
- 参数:除了self外,没有其他参数
- 返回值:不返回值,或者说返回None
语法:
def __del__(self):
# to do
class Dog:
# 构造
def __init__(self,name,kind,age):
self.name = name
self.kind = kind
self.age = age
# 析构
def __del__(self):
print('拜拜了,二十年后又是一条好汉')
def bark(self):
print('我是小可爱--丁丁')
dingding = Dog('丁丁','泰迪',3)
print('我是可爱的%s犬,%s,我今年%d岁了'%(dingding.kind,dingding.name,dingding.age))
del dingding # 销毁对象,自动调用析构方法,类似与遗嘱,并不是析构销毁他,而是它快结束,给析构返回消息
# 在函数中对象,当函数运行结束时,自动析构
def test():
td = Dog('当当','泰迪',3)
3.3 str
- 目的:将对象转换为字符串
- 时机:凡是设计对象向字符串转换的都会调用(print,str)
- 参数:self
- 返回值:字符串
__repr__作用同__str__,不过是给解释器看的
class Amimal:
def __init__(self,name,age):
self.name = name
self.__age = age
def __str__(self):
return "name : {} age : {} ".format(self.name,self.__age)
def __repr__(self):
return self.__str__()
a1 = Amimal('zhu',3)
print(a1)
print('我是一头可爱的' + str(a1))