私有化
本質(zhì)上艺玲,python中所有的屬性和方法都是公開的时鸵,在類的外部可以使用和繼承
1.私有化 - 讓屬性和方法只能在類的內(nèi)部使用缸废,不能在類的外部使用
語法:
聲明屬性或者方法的時候,在屬性名或者方法名前加‘_’
python私有化的原理:
python并不能像java一樣從訪問全線上去限制屬性和方法糖权,沒有真正的私有屬性和方法
私有化只是在兩個下劃線開頭的名字前加前綴'類名',導(dǎo)致不能直接通過原名進行訪問
class Person:
__num = 30 # 私有化
def __init__(self, name, gender, age=10):
self.name = name
self.age = age
self.__gender = gender
def eat(self, food='米飯'):
print('%s在吃%s' % (self.name, food))
print(Person.__num) # 在內(nèi)部使用私有化變量
print(p1.__gender)
p1 = Person('小明', '男', 25)
p1.eat()
2.對象屬性的保護:不要直接訪問或者修改對象屬性的值炸站,
而是通過屬性訪問器(getter)和修改器(setter)操作對象屬性
需要添加getter或者setter的對象屬性星澳,屬性命名的時候需要在前面加上'_',
添加下劃線的目的是告訴使用者旱易,這個屬性我給它加了getter或者setter
getter: - 獲取屬性的值(間接)
語法:
@property
def 函數(shù)名(self):
其他語句
return 屬性值
說明 - 對應(yīng)的屬性名去掉下劃線
屬性值 - 和對應(yīng)的下劃線的屬性值有關(guān)聯(lián)
什么時候使用:
如果希望在獲取某屬性的值之前做點什么事
setter - 給屬性賦值(間接賦值)
想要添加setter必須先添加getter
語法:
@getter名.setter
def 函數(shù)名(self, 參數(shù))
其他語句
self.屬性 = 參數(shù)
什么時候使用:
如果在給屬性賦值的之前想干點別的事
class Student:
def __init__(self, name):
self._name = name
self._week = 1
self._age = 18
@property
def name(self):
return self._name
@property
def age(self):
return self.age
@age.setter
def age(self, value):
if isinstance(value, int):
if value < 0 or value > 200:
print('年齡只能在0-200之間')
self._age = 0
else:
self._age = value
else:
print('年齡只能是整數(shù)禁偎!')
self._age = 0
@property
def week(self):
if self._week == 1:
return '星期一'
elif self._week == 2:
return '星期二'
elif self._week == 3:
return '星期三'
elif self._week == 4:
return '星期四'
elif self._week == 5:
return '星期五'
elif self._week == 6:
return '星期六'
elif self._week == 7:
return '星期日 '
stu1 = Student('小明')
# print(stu1._name) 無法獲取到name
print(stu1.name) # 獲取通過不帶下劃線去獲取屬性值的時候腿堤,本質(zhì)是在調(diào)用屬性值對應(yīng)的getter方法,獲取返回值
print(stu1.week)
stu1.age = 150
練習(xí):聲明矩形類如暖,有屬性:長寬笆檀,周長,面積要求修改長和寬的值的時候盒至,周長和面積自動變化并且不能修改周長和面積的值(如果直接給周長和面積賦值酗洒,程序直接報錯)
class Rect:
def __init__(self, long, width):
self._long = long
self._width = width
self._perimeter = (long + width) * 2
self._area = long * width
@property
def long(self):
return self._long
@long.setter
def long(self, value):
self._long = value
self._perimeter = (self._long + self._width) * 2
self._area = self._long * self._width
@property
def width(self):
return self._width
@width.setter
def width(self, value):
self._width = value
self._perimeter = (self._long + self._width) * 2
self._area = self._long * self._width
@property
def perimeter(self):
return self._perimeter
@perimeter.setter
def perimeter(self, value):
raise ValueError
@property
def area(self):
return self._area
@area.setter
def area(self, value):
raise ValueError
r1 = Rect(5, 5)
print('周長:', r1.perimeter, '面積:', r1.area)
r1.long = 10
print('周長:', r1.perimeter, '面積:', r1.area)
r1.witth = 10
print('周長:', r1.perimeter, '面積:', r1.area)
類中的方法
1.類中的方法:對象方法、類方法枷遂、靜態(tài)方法
對象方法:
a.怎么聲明:直接聲明在類中
b.特點:自帶self參數(shù),調(diào)用的時候不用傳參樱衷,指向當(dāng)前對象
c.怎么調(diào)用:對象. 的方式調(diào)用
d.什么時候使用:如果實現(xiàn)函數(shù)的功能,需要使用對象屬性酒唉,就用對象方法
類方法:
a.怎么聲明:聲明函數(shù)前添加@classmethon裝飾器
b.特點:有默認cls參數(shù)箫老,調(diào)用的時候不傳參,系統(tǒng)將調(diào)用這個方法的類傳給它黔州,指向當(dāng)前類
c.怎么調(diào)用:通過類來調(diào)用
d.什么時候使用:在不需要對象屬性的前提下耍鬓,需要類的字段,就用類方法
靜態(tài)方法:
a.怎么聲明:聲明前添加@staticmethod裝飾器
b.特點:沒有默認參數(shù)
c.怎么調(diào)用:通過類調(diào)用
d.什么時候使用:既不需要對象的屬性流妻,也不需要類的字段牲蜀,就是用靜態(tài)方法
class Person:
num = 60
def __init__(self, name, age):
self.name = name
self.age = age
# 對象方法
def eat(self, food='屎'):
print('%s 在吃 %s' % (self.name, food))
# 類方法
@classmethod
def show(cls):
print('這是一個類方法')
# cls:當(dāng)前類能做的事情,cls都能做
print(cls.num) # 使用類的字段
p2 = cls('大黃', 29) # 創(chuàng)建對象
print(p2.__dict__)
# 靜態(tài)方法
@staticmethod
def static():
print('這是一個靜態(tài)方法')
p1 = Person('小明', 28)
p1.eat() # 調(diào)用對象方法
Person.show() # 通過類調(diào)用類方法
Person.static() # 通過類調(diào)用靜態(tài)方法
繼承
1.繼承
繼承者 - 子類
被繼承者 - 父類
繼承 - 就是讓子類擁有父類的屬性和方法
語法:
class 類名(父類):
類的內(nèi)容
2.在子類中添加內(nèi)容
在子類中添加字段和方法:
直接在子類中聲明新的字段和方法
添加對象屬性:
在子類中實現(xiàn)init方法绅这,添加新屬性涣达,同時通過super().init()調(diào)用父類的init方法
補充:類中函數(shù)調(diào)用的過程
先看當(dāng)前類中是否有這個方法,如果有直接調(diào)用自己的方法证薇,如果沒有就去看父類有沒有這個方法度苔,
如果有就調(diào)用父類的方法,如果父類也沒有找到父類的父類浑度,以此類推寇窑,如果找到object都沒有找到這個
方法才會報錯
python中的所有類都默認繼承object, object是python所有類的基類
3.重寫
在子類中重寫父類的方法:
可以通過super()去調(diào)用父類的方法
注意:super()不能在靜態(tài)方法中使用箩张,只能在對象方法和類方法中使用
class Person:
num = 61
def __init__(self):
self.name = '張三'
self.age = 0
self.gender = '女'
def eat(self, food):
print('%s 在吃 %s ' % (self.name, food))
@staticmethod
def run():
print('人跑步')
class Student(Person):
num = 100 # 重寫
id_pre = 'stu'
@staticmethod
def study():
print('好好學(xué)習(xí)甩骏,天天吃飯')
def __init__(self):
super().__init__() # 調(diào)用父類的__init__方法
self.stu_id = '001'
self.score = 0
@classmethod
def run(cls):
print('++++++子類繼承父類方法+++++++')
super().run() # 調(diào)用父類的方法
print('學(xué)生跑步')
print(Student.num)
stu = Student()
print(stu.name, stu.age, stu.gender)
stu.eat('蟑螂')
Student.study()
print(stu.name, stu.stu_id)
Person.run()
Student.run()