1.面向對象 c1.py
# 面向對象
# 有意義的面向對象的代碼
# 類,對象
# 類:
# 類的名字的第一個字母大寫,第二個單詞的首字母大寫(函數/方法的首字母小寫,第二個單詞的首字母小寫並且兩個單詞之間通過下劃線連接)
# 類的名字後跟括號,括號後跟冒號
# 類裏的'函數'不叫函數(稱爲方法);
# 不論涉及參數與否,類裏的實例方法都必須傳一個self關鍵字(否則會報錯,其實這裏的這個self也可叫別的名字,就和this一樣;
# 但實際中約定俗成使用self這個名字;
# 在js中this不需要顯示的聲明,但這裏需要;
# 這裏的self就是實例方法的對象)
# 類裏邊的方法訪問類裏的函數,必須通過slef關鍵字加'.'操作符來實現
# 類的實例化,不需要通過new這個關鍵字來實現,直接使用類名加括號實例化即可
# 在類裏邊不能直接調用類的方法,會報錯,只能在類的外邊,實例化類以後同過點操作符來調用 (只負責定義,運行在外部)
# 類的最基本的作用:封裝代碼
# 方法和函數的區別:
# 方法:設計層面
# 函數:程序運行,過程式的一種稱謂
class StudentHome():
name = 'qiyue' # 這個在類中一般不叫變量,而叫 數據成員(更能體現類的封裝性)
age = 0
# 須傳入self參數,這是一個固定的特徵
def print_file(self):
print('name: '+self.name)
print('age: '+ str(self.age))
# 實例化類,通過類名+括號
# student = StudentHome()
# 調用類下的方法
# student.print_file()
2.使用 c2.py
# 在一個模塊裏定義一個類
# 在另一個模塊引入,調用
from c1 import StudentHome
student = StudentHome()
student.print_file()
3.類和對象的區別 c3.py
# 類和對象的區別
# 類:是現實世界或者思維世界中的實體在計算機中的反映,它將數據以及這些數據上的操作封裝在一起;
# 類就像模板一樣,通過類可以產生很多個對象;(類可以通過傳入不同的具體值,可以產生很多個對象)
# 數據成員:刻畫特徵
# 方法:行爲
# 構造函數:
# (1)自動執行,在實例化的時候自動觸發(不需要顯示的調用,但是是可以顯示的調用的)
# 如果顯示調用返回結果是none,不能強制返回(會報錯);若想有返回,可以定義一個方法,在方法中return
# (2)構造函數會返回一個none,不能強制給一個return的值,會報錯。所以一般不會通過構造函數return一個值,如果需要return一個值,還是通過普通函數來實現吧!
# (3)可以通過構造函數來使模板生成不同的對象
# (4)初始化類的屬性
# (5)須加self參數
# (6)當直接打印構造函數的某個變量,如果該函數沒有,則會往上尋找類的變量,若類的變量存在則打印類的變量
class Student():
# 這兩個是類變量
name = 'qiyue'
age = 0
# 構造函數
# 類變量和實例變量(是不同的)
# 類變量:和類相關的變量
# 實例變量:和對象相關聯一起的 (這個對象是有類這個模板創建的)
# 須加self
def __init__(self,name,age):
# 在這裏給和對象相關的實例變量賦值
self.name = name
self.age = age
# 初始化類的屬性
# print('do homework')
def do_homework(self):
print("do homework")
# 當類被具體實例化後,就變成了一個對象,
# (在類實例化過程中向類裏傳遞一些具體參數,如果沒有具體的數據的話就不是一個對象(因爲還不具體,還是很抽象))
# 如果在__init__初始化的構造函數中有參數傳入,則在實例化時必須也要傳入參數,否則會報錯
student1 = Student('石敢當',18)
student2 = Student('喜小樂',19)
print(student1.name)
print(student2.name)
# 在類的外部訪問類的變量,通過 類名.變量名 的方式
print(Student.name)
4.類方法,靜態方法,實例方法,構造方法 c4.py
# 訪問類的變量,通過類的名字加'.'加類的變量名來訪問
# 在類的內部還可通過self.__class__.類變量名來訪問
# 類方法
# (1)一般使用cls(約定俗成)
# (2)通過@classmethod(裝飾器)來聲明是類方法
# (3)在類方法裏訪問類變量,直接通過cls.sum1(這裏的cls就是這個類方法的類)即可
# (4)調用,是通過Student.add_sum來使用
# 類方法和實例方法的區別
# 實例方法關聯的是實例本身,類方法關聯的是類本身
# 類方法須加 @classmethod(類方法的裝飾器)
# 類方法訪問類變量直接 cls.sum2 (即 類.變量名) 就行;而實例方法須使用 self.__class__.sum1 實現;
# 靜態方法
# (1)不需要像類方法和實例方法一樣傳入一個cls或者self
# (2)通過@ staticmethod(裝飾器)聲明靜態方法
# (3)通過類或者實例來調用都可以
# (4)在其內部也可以訪問類變量,通過Student.sum1(類名.類變量名)
# 注意點
# 不論是類方法還是靜態方法都不能訪問實例方法裏的變量,所以建議直接使用類方法或者實例方法,少用靜態方法(因爲前兩種,都辦到它所實現的功能)
class Student():
sum1 = 0
sum2 = 0
name = 'qiyue'
age = 0
# 構造函數
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.sum1 += 1
# 訪問類的變量名
# 在類的外部訪問類的變量,通過 類名.變量名 的方式 ,例如:print(Student.sum1)
# 在類的內部還可通過 self.__class__.類變量名 來訪問 (這裏的 __class__ 指的就是 類 )
print('當前學生總數爲: ' + str(self.__class__.sum1))
# 實例方法
# (定義時須傳入self,在使用時不需要傳參的;
# self只和對象有關,和類無關,誰調用了這個方法,這個self值的就是誰
# 即self指的是實例,而不是類)
def do_homework(self):
# self 指對象本身
print('do homework')
# 類方法
@classmethod # 類方法的裝飾器
def add_sum(cls):
# 這裏的cls指類本身
cls.sum2 += 1
print('sum2: ' + str(cls.sum2))
# 靜態方法
@staticmethod # 靜態方法的裝飾器
def static_sum(x,y):
print(Student.sum1)
print('i am a static method')
student1 = Student('石敢當',18)
Student.add_sum()
# 通過對象也可調用類方法,但不建議這麼做,最好使用類來調用類方法,例如:student1.add_sum()
student2 = Student('喜小樂',13)
# 類方法的調用
# 通過 類名.類方法名() 的方式
Student.add_sum()
# print(Student.sum1)
# 靜態方法
# 可以通過類來調用;也可以通過對象來調用
Student.static_sum(1,2)
student1.static_sum(1,2)
5.成員的可見性 c5.py
# 成員的可見性
# public 公開的 private 私有的
# 如果想讓某個方法(或者變量)私有 在這個方法(或者變量)前加雙下劃線(變量亦如此,前邊加雙下劃線即可變爲私有的變量)
# 例如:self.__score ; __add()之類的
# 內部方法和外部方法
# 類裏的變量(即類的成員)的修改都應該通過方法來實現,而不應該通過直接對類的變量進行修改來實現(
# 通過方法來修改,可以在方法中做一些處理,對類的成員進行保護)
class Student():
name = 'qiyue'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 0
def __priv_method(self):
print('private')
def marking(self,score):
self.__score = score
print(self.name + '同學的成績是: ' + str(self.__score) +'分')
def do_homework(self):
print('do homework')
def do_english_homework(self):
# 內部調用
self.do_homework()
print('do english homework')
student1 = Student('石敢當',18)
student2 = Student('小愛',18)
# 通過方法的方式來修改變量的值,比較提倡,
# 在方法中可以做一些邏輯處理(例如:不能打負分,當爲負分時給提示之類的;
# 如果是變量,不能做邏輯處理判斷,但方法就比較靈活了)
student1.marking(59)
# 私有方法,調用報錯
# student1.__priv_method()
# 外部調用
# student1.do_homework()
# 這裏並不是改變了私有變量__score的值,而是Python動態語言的特性,給student1擴展了一個__score變量(例如打印student2.__score就會報錯)
student1.__score=-1
print(student1.__dict__)
print(student2.__dict__)
# print(student1.__score)
# print(student2.__score)
6.面向對象的三大特性 c6.py
# 面相對象的三大特性
# (1)繼承性
# (2)封裝性
# (3)多態性
class Human():
sum = 0
def __init__(self,name,age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
def do_homework(self):
print('this is parent method')
7.類的引入 c7.py
# 第一種寫法,直接通過import,在使用時需要寫爲C6.Peopel
# import c6
# 第二種寫法 通過from (推薦),使用時直接傳入類的名字即可
from c6 import Human
class Student(Human):
def __init__(self,school,name,age,):
self.school = school
# 第一種調用方式: 不推薦使用該方法,如果使用了幾十次,有一天父類變了,那就得改幾十處名字,不太可取
# 這裏是通過類來調用實例方法,所以必須要傳入self
# Human.__init__(self,name,age)
# 第二種調用方式:通過super(第一個參數爲子類的類名,第二個參數爲需要傳入的self參數) 這種方式比較推薦
# 優點:只需要更換括號中傳入的父類名稱即可,很方便
# super:父類的關鍵字
# super關鍵字不僅可用在構造函數中,也可用在其他的方法中
super(Student,self).__init__(name , age)
def do_homework(self):
super(Student,self).do_homework()
print('do son homework')
# 在父類中初始化須傳入一些參數,子類繼承後也須傳入這些參數,同時須加上子類的初始化的參數
student1 = Student('人民路小學','石敢當',18)
# 通過類來調用實例方法,必須要傳入self(這個有點可笑
# 既然已經將類實例化了,就可以直接通過實例化的student1.do_homework()
# 來調用即可,不必再次傳入,而顯得那麼繁瑣 )
# Student.do_homework(student1)
# 繼承父類 (子類中是沒有sum這個變量的,繼承了父類)
# print(Student.sum)
print(student1.school)
print(student1.name)
print(student1.age)
# 允許,子類和父類的方法同名
# 當同名並不會報錯
student1.do_homework()
# 開閉原則
# 修改封閉,擴展開放
(備註:以上內容來自七月老師的學習筆記,僅作爲學習使用)