類&成員可見性&繼承
類
類名定義:
- 第一個字母大寫
- 多個單詞時,使用駝峰式,如StudentHomework
Tips:
現實世界事務的特徵和行為,抽象到類就是資料成員和方法。
例項化物件時,會自動呼叫__init__()函式。
self: 當前呼叫該方法的物件。
變數
例項變數
python 在__init__函式內定義例項變數。
嘗試訪問一個例項變數時,python首先會在物件的例項變數列表查詢,如果找不到,則到類變數列表尋找,如果還找不到,則到其父類中尋找。
- __dict__儲存了物件/類的屬性。
student = Student('娜可露露',23)
print(student.__dict__)
print(Student.__dict__)
#執行結果
> python p\p2.py
{'name': '娜可露露', 'age': 23}
PS E:\word\Python\code\abc> python p\p2.py
{'name': '娜可露露', 'age': 23}
{'__module__': '__main__', 'sum': 1, '__init__': <function Student.__init__ at 0x0000023C61AFDF70>, 'print_file': <function Student.print_file at 0x0000023C61B04040>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
類變數
例項方法中訪問類變數:
- 類名.變數名
-
self.__class__.變數名
class Student():
num_sum = 0
name = 'qiyue'
def __init__(self,name,age):
self.name = name
self.age = age
print(Student.num_sum)
print(self.__class__.num_sum)
print(Student.num_sum)
方法
例項方法
通過類呼叫例項方法,需要傳一個引數給self形參,self此時就是一個普通引數。
class Student():
num_sum = 0
# name = 'qiyue'
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 0
def do_homework(self):
print('day day up')
student = Student('娜可露露',23)
Student.do_homework(student)
Student.do_homework(1)
類方法
定義
@classmethod
def plus_sum(cls):
pass
在類方法中操作類變數
class Student():
num_sum = 0
@classmethod
def plus_sum(cls):
cls.num_sum += 1
print('當前學生總數為:',cls.num_sum)
Student.plus_sum() #通過類名呼叫類方法
student.plus_sum() #通過物件也可以呼叫類方法
類方法內部 不能訪問例項變數。
靜態方法
定義
@staticmethod
def add(x,y):
pass
呼叫
類和物件都可以呼叫靜態方法。
student = Student('娜可露露',23)
Student.add(4,5)
student.add(2,3)
靜態方法內部可以訪問類變數。
class Student():
num_sum = 0
@staticmethod
def add(x,y):
print(Student.num_sum)
靜態方法內部不可以訪問例項變數。
Tips:
能用靜態方法的地方都可以用類方法來代替,當所定義函式跟類/物件沒太大關聯時使用靜態方法。
成員可見性
私有屬性/方法
在python中,一個變數/方法開頭是雙下劃線“__”,則認為該變數/方法是私有的。
前後都有雙下劃線,認為是公開的,比如__init__()。
class Student():
def __marking(self,score):
pass
#呼叫會報錯
student = Student('娜可露露',23)
print(student.__marking(-1))
#執行結果
> python p\p2.py
Traceback (most recent call last):
File "E:\word\Python\code\abc\p\p2.py", line 35, in <module>
print(student.__marking(-1))
AttributeError: 'Student' object has no attribute '__marking'
仍然可以訪問私有屬性?
如果直接給私有屬性賦值/讀取,程式不會報錯。
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 0
student = Student('娜可露露',23)
student.__score = 100
print(student.__score)
原因是:由於python動態語言的特性,實際上是給物件新增加了一個屬性。
示例:
student = Student('娜可露露',23)
student2 = Student('橘子',20)
student.__score = 100
print(student.__score)
print(student.__dict__)
print(student2.__dict__)
print(student2.__score)
#執行結果
> python p\p2.py
100
{'name': '娜可露露', 'age': 23, '_Student__score': 0, '__score': 100}
{'name': '橘子', 'age': 20, '_Student__score': 0}
Traceback (most recent call last):
File "E:\word\Python\code\abc\p\p2.py", line 43, in <module>
print(student2.__score)
AttributeError: 'Student' object has no attribute '__score'
分析:
可以看到student物件的屬性包括'_Student__score'和 '__score',其中'_Student__score'是建構函式中定義的私有屬性(python自動改名),'__score'是後來動態新增的屬性。
而student2物件就不包括屬性'__score'。
因此還可以得出一個結論:不能動態新增私有屬性。
其實仍然可以訪問
可以通過改名後的屬性名來訪問該私有屬性。
student = Student('娜可露露',23)
student._Student__score = 99
print(student._Student__score)
執行結果:
> python p\p2.py
99
繼承
python支援多繼承。
呼叫父類構造方法
一種顯式呼叫父類建構函式的方法(一般不使用):
class Human():
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 0
class Student(Human):
def __init__(self,school,name,age):
self.school = school
Human.__init__(self,name,age) #呼叫父類構造方法
主流呼叫方式::
class Student(Human):
def __init__(self,school,name,age):
self.school = school
super(Student,self).__init__(name,age)
相關文章
- c#繼承父子類成員間的互訪問性C#繼承
- 使用類繼承還是類的成員變數繼承變數
- oop類的繼承與類靜態成員學習OOP繼承
- css可繼承屬性和非繼承屬性一覽CSS繼承
- css屬性的可繼承性CSS繼承
- 18、繼承以及繼承中成員變數和成員方法的重名問題繼承變數
- 類的繼承_子類繼承父類繼承
- 介面是否可繼承(extends)介面? 抽象類是否可實現 (implements)介面? 抽象類是否可繼承具體類(concrete class)?繼承抽象
- python入門基礎(14)--類的屬性、成員方法、靜態方法以及繼承、過載Python繼承
- JS原型繼承和類式繼承JS原型繼承
- python 類繼承,對類屬性的改變Python繼承
- 類的繼承繼承
- javascript類繼承JavaScript繼承
- [譯] 繼承 JavaScript 類中的靜態屬性繼承JavaScript
- Java基礎 成員變數的繼承與覆蓋Java變數繼承
- TypeScript 介面繼承類TypeScript繼承
- 原型繼承:子類原型繼承
- C++ | 類繼承C++繼承
- iOS 繼承&類方法iOS繼承
- Java:類與繼承Java繼承
- JAVA物件導向高階:繼承:許可權修飾符(繼承注意事項) 單繼承 Object類 方法重寫Java物件繼承Object
- 繼承 基類與派生類繼承
- 繼承關係裡的六個預設成員函式繼承函式
- #JAVA#物件導向(繼承中成員方法的關係)Java物件繼承
- Java繼承中成員方法的overload(過載/過載)Java繼承
- Python類的繼承Python繼承
- 繼承+多型+抽象類繼承多型抽象
- 類的繼承圖解繼承圖解
- Java的類與繼承Java繼承
- Swift—類的繼承-備Swift繼承
- 類的繼承和派生繼承
- es5繼承和es6類和繼承繼承
- 征服 JavaScript 面試:類繼承和原型繼承的區別JavaScript面試繼承原型
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- 從本質認識JavaScript的原型繼承和類繼承JavaScript原型繼承
- PHP 抽象類繼承抽象類時的注意點PHP 抽象類繼承抽象類時的注意點PHP抽象繼承
- 【Hello CSS】第七章-CSS的繼承與可變性CSS繼承
- 物件、原型鏈、類、繼承【上】物件原型繼承