面向对象的编程都具有三大特征: 封装,继承,多态
python也为面向对象语言
以例子说明:
class user(object):
def __init__(self, name, age,work):
self.name = name
self.age = age
self.work = work
def __str__(self): #拼接字符串
return self.__name + str(self.__age) + str(self._work)
if __name__ == '__main__':
u = user("嘻嘻",19,"doctor")
print(u)
print(u.name) #直接访问对象属性
u.name = "xixi" #可以被直接修改
print(u)
运行结果:
通过直接访问属性,缺点:
(1)数据可能会被篡改
(2)类变的难以维护易出错
为了防止上面的情况,所以我们将其属性私有化,不让其直接访问,私有化的属性和方法在内部可以被访问,但不能再类外被访问,只有提供公开方法才会被访问和修改,这就是封装。
一,封装
概念:类将属性和方法封装成一个整体,并实现不能直接访问保密的属性。
封装的几种方法:
(1)直接私有化属性,提供getter和setter
格式: self.__属性名 = 属性值
若类外想要获取或设置对象属性
使用get,set方法。
class user(object):
def __init__(self, name, age,work):
self.__name = name
self.__age = age
self.__work = work
def get_name(self): # __get_name 方法私有化
return self.__name
def set_name(self, name):
self.__name = name
#age,work属性get,set同上name的
def __str__(self):
return self.__name + str(self.__age) + str(self.__work)
if __name__ == '__main__':
u = user("嘻嘻",19,"doctor")
#(1)
print(u)
u.name = "xixi" #也不能在外界修改或赋值,运行结果依然显示之前的,未修改成功。
print(u) #依然可以访问私有化属性,会调用 __str__(self),会访问到自身属性,因为__str__(self)是类里的方法
print(u.__name) #一旦私有化将无法访问,将会报错。使用print(u.name)也报错
使用公开的方法:
(1)如果要修改属性值,使用set(设置),get(获取)方法(类种提供的公开方法。
print(u.get_name())
u.set_name("zhang")
print(u.get_name())
(2),直接私有化属性,提供getter和setter,引入了property的全局函数
property全局函数,在定义好的类里使用,将封装后的属性,进一步操作,给外界造成错觉,没有封装,获取和修改时同没有私有化一样。
class user(object):
def __init__(self, name, age,work):
self.__name = name
self.__age = age
self.__work = work
def get_name(self): # __get_name 方法私有化
return self.__name
def set_name(self, name):
self.__name = name
def __str__(self):
return self.__name + str(self.__age) + str(self.__work)
name = property(get_name, set_name) # get_name无(),引用传递,有是调用。
#这里只写了name属性,其他属性一样
if __name__ == '__main__':
u = user("嘻嘻",19,"doctor")
print(u.name)
u.name = "hehe"
print(u.name)
print(u)
(3)使用property装饰器完成封装
class user(object):
def __init__(self, name, age,work):
self.__name = name
self.__age = age
self.__work = work
def get_name(self): # __get_name 方法私有化
return self.__name
def set_name(self, name):
self.__name = name
def get_age(self):
return self.__age
def set_age(self, age):
self.__age = age
def __str__(self):
return self.__name + str(self.__age) + str(self.__work)
#@property装饰器来封装,此时work并没有提供get,set方法
@property
def work(self):
return self.__work
@work.setter
def work(self,work):
self.__work = work
if __name__ == '__main__':
u = user("嘻嘻",19,"doctor")
print(u.work)
u.work = "teacher"
print(u.work)
运行:
注意:
def work(self):
return self.__work
def work(self,work):
self.__work = work
若没有@两行,python是解释型语言(对应的是编译型语言)没有方法重载,方法名称相同,参数个数和类型不同。第一个方法会被第二个相同的方法覆盖,解释型语言一行一行执行,一旦有一行错误,后面的代码将不执行,但编译型语言会根据参数和类型的不同来执行。