24. 企業級開發基礎5:物件導向特徵(封裝)
物件導向程式設計最主要的有三個特徵:封裝、繼承、多型
本節內容主要講解物件導向的第一個特徵:封裝
1 封裝的意義
在我們程式開發過程中,定義好型別之後就可以通過型別來建立物件 如:我們定義一箇中華人民共和國公民的型別 ```
# 建立一個人的型別
class Person(object):
def __init__(name, age):
self.name = name
self.age = age
此時如果我們建立好物件之後,對物件的資料進行如下修改,大家是否認為合適呢?
# 建立一個人的物件
xiaoMing = Person("小明", 18)
# 修改屬性
xiaoMing.age = 1000
``` 我們會發現,上面的程式碼在執行時是正確的,也就是可以修改age屬性為1000 此時我們需要明確一個概念:程式碼執行正確,但是不代表符合業務邏輯,這樣的程式碼我們一般會說程式碼處理不合法!
2. 實現封裝的過程
對於上面這樣的問題,我們應該怎麼處理呢 常規的方案就是: 1. 定義一種這樣的屬性,屬性只有在當前類的內部可以訪問 2. 類的外部不能訪問這個屬性,只能通過類提供的方法來進行屬性的取值和賦值 3. 在取值或者賦值的方法中,就可以新增一定的限制處理的程式碼了
python中,提供了這樣的一種特殊的變數,變數名稱使用兩個下劃線開頭,這樣的變數智慧在類的內部訪問,類的外部是訪問不了的,我們稱之為私有屬性 ```
# 定義型別
class Person(object):
def __init__(self, name, age):
self.__name = name;
self.age = age
# 建立物件
xiaoMing = Person("小明明", 18)
# 訪問屬性
print(xiaoMing.age)
~ 18,可以訪問,age只是一個普通的成員屬性
print(xiaoMing.__name)
~ 出現錯誤,AttributeError: 'Person' object has no attribute '__name'
這樣我們就限制了變數的訪問範圍。
但是變數定義出來就是為了被訪問和操作的,如果上述程式碼中的__name一旦限制了不讓訪問,就木有存在的價值了。所以,我們通過自定義的方法給__name屬性新增訪問控制
# 建立一個人的型別
class Person(object):
# 物件的初始化方法
def __init__(self, name):
# 初始化私有成員變數__name
self.__name = name
# 定義獲取__name的函式
def get_name(self):
return self.__name
# 定義設定__name的函式
def set_name(self, name):
self.__name = name
# 根據型別建立物件
xiaoMing = Person("小明");
# 訪問資料
xiaoMing.set_name("小明明");
print(xiaoMing.get_name())
# 執行結果:小明明
OK,通過以上對屬性進行私有化(屬性名稱雙下劃線開頭),給屬性提供set/get的訪問方法完成封裝過程,此時就可以對本文開頭的年齡設定問題進行一定的邏輯限制了
# 定義一個人的型別
class Person(object):
# 初始化變數
def __init__(self, name, age):
self.__name = name
if(age >= 0 and age <= 100):
self.__age = age
else:
age = 18
# 定義訪問屬性的get方法
def get_name(self):
return self.__name
def get_age(self):
return self.__age
# 定義訪問屬性的get方法
def set_name(self, name):
self.__name = name;
def set_age(self, age):
if(age >= 0 and age <= 100):
self.__age = age
else:
print("您設定的年齡不合法,還原預設值")
# 建立物件
p = Person("張小凡", 19)
p.set_age(1000)
print(p.get_age())
# 執行結果
~ 您設定的年齡不合法,還原預設值
~ 19
``` 以上執行的結果,才是我們想要的結果
什麼是封裝 封裝,就是將物件敏感的資料封裝在類的內部,不讓外界直接訪問,但是提供了讓外界可以間接訪問的set/get方法,我們可以在set/get方法中新增資料的訪問限制邏輯,完善我們的程式碼,提高程式的健壯性
3. 封裝的高階使用方式
我們從上面的程式碼中已經看到了,可以通過函式操作的形式來進行屬性的處理 但是某些情況下,函式操作的形式並不是特別美妙,我們突發奇想~想再提供了set/get訪問方法的情況下,對屬性的操作還能像以前那樣直接賦值或者取值進行操作 ```
# 封裝以後通過函式操作的方式
p.set_name("tom")
print(p.get_name())
# 封裝以前通過屬性直接操作的方式
p.name = "tom"
print(p.name)
``` 將類中的set/get方法操作的形式,轉換成屬性直接操作的形式,python中是可以的
首先:給get方法上新增@property
註解,(關於註解的東東,之前的函式裝飾器章節中已經有使用,可以參考一下操作原理),就可以讓get方法當成屬性進行直接取值操作了
其次,@property
同時它會自動生成一個@get方法名稱.setter
註解,將@get方法名稱.setter
註解寫在set方法上,就可以讓set方法進行直接賦值操作了,程式碼如下:
```
class Person(object):
def __init__(self, name):
self.__name = name;
@property
def get_name(self):
return self.__name
@get_name.setter
def set_name(self, name):
self.__name = name
# 建立物件
p = Person("tom")
print(p.get_name)
p.set_name = "jerry"
print(p.get_name)
# 執行結果
~ tom
~ jerry
上述程式碼我們可以看出來,set/get方法已經可以當成普通的屬性取值賦值的方式進行快捷的操作了,我們繼續改造一下上述程式碼,讓set/get更加符合屬性取值賦值的方式
class Person(object):
def __init__(self, name):
self.__name = name;
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
# 建立物件
p = Person("tom")
print(p.name)
p.name= "jerry"
print(p.name)
# 執行結果
~ tom
~ jerry
``` 此時,你還能在不看原來型別定義中的get/set,區分出來name是否是Person型別的屬性還是方法呢?
封裝的註解方式,在一定程度上,能隱藏我們方法在底層的實現,讓呼叫者的操作變得簡單。但是同時也降低了程式碼的可讀性,後續的操作中,我們還是遵循原來封裝的操作方案將類的屬性私有化,提供set/get方法進行屬性的操作。
相關文章
- 26. 企業級開發基礎7:物件導向特徵(多型)物件特徵多型
- 25. 企業級開發基礎6:物件導向特徵(繼承)物件特徵繼承
- 23. 企業級開發基礎4:物件導向物件
- 27. 企業級開發基礎8:物件導向擴充套件物件套件
- java物件導向的三大特徵之封裝Java物件特徵封裝
- 【Java基礎】物件導向開發Java物件
- [.net 物件導向程式設計基礎] (11) 物件導向三大特性——封裝物件程式設計封裝
- JAVA物件導向基礎--封裝 繼承 多型Java物件封裝繼承多型
- 【Java】瘋狂Java基礎(一)——物件導向的特徵:繼承、封裝和多型Java物件特徵繼承封裝多型
- 物件導向三大特徵(封裝/繼承/多型)物件特徵封裝繼承多型
- iOS開發-物件導向三大特徵iOS物件特徵
- 前端基礎進階(10):物件導向實戰之封裝拖拽物件前端物件封裝
- [JAVA] Java物件導向三大特徵:封裝、繼承、多型Java物件特徵封裝繼承多型
- 22. 企業級開發基礎3:類和物件物件
- 物件導向基礎物件
- 物件導向:封裝,多型物件封裝多型
- 物件導向之封裝(Java)物件封裝Java
- 對FMDB物件導向封裝物件封裝
- JAVA(一)JAVA基礎/物件導向基礎/高階物件導向Java物件
- JAVA物件導向基礎--物件導向介紹Java物件
- 物件導向的三個基本特徵是:封裝、繼承、多型物件特徵封裝繼承多型
- js物件導向封裝級聯下拉選單列表JS物件封裝
- Java基礎-物件導向基礎Java物件
- ES5物件導向基礎結構物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- JAVA物件導向基礎Java物件
- PHP物件導向基礎PHP物件
- 【Java 基礎】——物件導向Java物件
- Java基礎 --- 物件導向Java物件
- JavaScript物件導向之一(封裝)JavaScript物件封裝
- 複習java物件導向(封裝)Java物件封裝
- 物件導向08:封裝詳解物件封裝
- 20. 物件導向之封裝物件封裝
- 物件導向三大特徵物件特徵
- 物件導向 -- 三大特性之封裝物件封裝
- PHP 物件導向基礎概念PHP物件
- java基礎二:物件導向Java物件
- python物件導向[基礎]Python物件