您好,登錄后才能下訂單哦!
類的兩種類型:
經典類:
class Person():#沒有繼承object
Pass
新式類:
class Person(object):#繼承object
pass
面向對象技術簡介
類(Class):用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作為實例變量使用。
數據成員:類變量或者實例變量用于處理類及其實例對象的相關的數據。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
實例變量:定義在方法中的變量,只作用于當前實例的類。
繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許
把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關系(例圖,Dog是一個Animal)。
實例化:創建一個類的實例,類的具體對象。
方法:類中定義的函數。
對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法
創建類
#coding=utf-8
class Employee(object):
empCount = 0
def __init__(self,name,salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print("total employee",Employee.empCount)
def displayEmployee(self):
print("name:",self.name,",salary:",self.salary)
empCount變量是一個類變量(也叫靜態變量),它的值將在這個類的所有實例之間共享。你可以在內部類或外部類使用Employee.empCount訪問。類中第一個方法init()是一種特殊方法,被稱做類的構造函數或初始化方法,只要創建類的實例,就會調用這個方法。如果沒顯示定義這個方法,默認會給一個空的構造方法。類方法中參數中的self,代表實例本身,相當于java中的this指針。并且類中所有的方法中都必須有self,并且寫在第一個參數位置。所有類都是繼承至基類object。
類和對象在內存中的保存
類以及類中的方法在內存中只有一份,而根據類創建的每一個對象都在內存中需要存一份
如上圖所示,根據類創建對象時,對象中除了封裝 name 和 age 的值之外,還會保存一個類對象指針,該值指向當前對象的類。當通過 obj1 執行 【方法一】 時,過程如下:根據當前對象中的 類對象指針 找到類中的方法將對象 obj1 當作參數傳給 方法的第一個參數 self
面向對象應用場景
函數式的應用場景 --> 各個函數之間是獨立且無共用的數據
面向對象編程的應用場景→各個函數公用一組數據
封裝1
封裝,顧名思義就是將內容封裝到某個地方,以后再去調用被封裝在某處的內容。
在使用面向對象的封裝特性時,需要:
將內容封裝到某處
從某處調用被封裝的內容
self 是一個形式參數,當執行 obj1 = Foo('wupeiqi', 18 ) 時,self 等于 obj1
當執行 obj2 = Foo('alex', 78 ) 時,self 等于 obj2;
所以,內容其實被封裝到了對象 obj1 和 obj2 中,每個對象中都有 name 和 age屬性,在內存里類似于下圖來保存:
調用封裝的內容
調用被封裝的內容時,有兩種情況:
通過對象直接調用
通過 self 間接調用
1、通過對象直接調用被封裝的內容
上圖展示了對象 obj1 和 obj2 在內存中保存的方式,根據保存格式可以如此調用被封裝的內容:對象.屬性名
2、通過self間接調用被封裝的內容執行類中的方法時,需要通過self間接調用被封裝的內容
通過對象直接調用
#coding=utf-8
class Foo:
def init(self,name,age):
self.name = name
self.age = age
obj1 = Foo("huhongiang",20)
print(obj1.name)# 直接調用obj1對象的name屬性
print(obj1.age)# 直接調用obj1對象的age屬性
obj2 = Foo("alex",73)
print(obj2.name)
print(obj2.age)
通過self間接調用被封裝的內容
#coding=utf-8
class Foo:
def init(self,name,age):
self.name = name
self.age = age
def detail(self):
print(self.name)
print(self.age)
obj1 = Foo("huhongiang",20)
obj1.detail()
#python將obj1參數傳遞給self參數,即obj1.detail(obj1),此時方法內部self == obj1,所以self.name == obj1.name, self.name 就是huhongiang,self.age就是20
obj2 = Foo("alex",73)
obj2.detail()
類成員
字段
字段包括:普通字段和靜態字段,他們在定義和使用中有所區別,而最本質的區別是內存中保存的位置不同
普通字段屬于對象
靜態字段屬于類
#coding=utf-8
class Province:
#靜態字段,類變量
country = "中國"
def init(self,name):
#普通字段
self.name = name
obj = Province("河北省")
print(obj.name)#直接訪問普通字段
print(Province.country)#直接訪問靜態字段
靜態字段在內存中只保存一份
普通字段在每個對象中都要保存一份
類變量可以被類和實例對象訪問,但是實例變量只能被實例對象訪問
方法
方法包括:普通方法、靜態方法和類方法,三種方法在內存中都歸屬于類,區別在于調用方式不同。
普通方法:由對象調用;至少一個self參數;執行普通方法時,自動將調用該方法的對象賦值給self;
類方法:由類調用; 至少一個cls參數;執行類方法時,自動將調用該方法的類復制給cls;
靜態方法:由類調用;無默認參數
示例:
#coding=utf-8
class Foo(object):
def init(self,name):
self.name = name
#普通方法,需要默認的self參數
def ord_func(self):
print(self.name)
print("普通方法")
#類方法,需要默認cls參數,cls代表類本身
@classmethod
def class_func(cls):
print("類方法")
#靜態方法,不需要默認參數
@staticmethod
def static_func():
print("靜態方法")
#return self.name#靜態方法不能訪問實例變量,靜態方法可以訪問類變量(靜態變量)
f = Foo("gloryroad")
f.ord_func()#對象調用普通方法,不能用類調用
Foo.class_func()#直接用類名調用類方法
Foo.static_func()#直接用類名調用靜態方法
#靜態方法和類方法也可以由對象調用
f.class_func()
f.static_func()
Foo.ord_func() #但是不能由類直接調用普通方法(實例方法)
Foo.name #類也不能訪問實例變量
相同點:對于所有的方法而言,均屬于類(非對象)中,所以,在內存中也只保存一份。
不同點:方法調用者不同、調用方法時自動傳入的參數不同
類的屬性
Python中的屬性其實是普通方法的變種。
@property
定義時,在普通方法的基礎上添加 @property 裝飾器;定義時,屬性僅有一個self參數;
調用時,無需括號
方法調用:foo_obj.func()
屬性調用:foo_obj.prop
注意:屬性存在意義是:訪問屬性時可以制造出和訪問字段完全相同的假象,屬性由方法變種而來,如果Python中沒有屬性,方法完全可以代替其功能。
#coding=utf-8
class Foo(object):
def func(self):
print("func")
#定義屬性
@property
def prop(self):
return "gloryroad"
foo_obj = Foo()
foo_obj.func()
print(foo_obj.prop)#調用屬性不需要括號
@method_name.setter @method_name.deleter
定義時在普通方法的基礎上添加@method_name.setter裝飾器,賦值操作時候自動執行被修飾的方法;添加@method_name.deleter裝飾器,del 刪除
#coding=utf-8
class Goods(object):
@property
def price(self):
print("@property")
return "hhq"
@price.setter
def price(self,value):
print("@price.setter")
print(value)
@price.deleter
def price(self):
print("@price.deleter")
obj = Goods()print(obj.price)#自動執行@property修飾的方法,并獲得返回值
br/>print(obj.price)#自動執行@property修飾的方法,并獲得返回值
del obj.price#自動執行@price_deleter修飾的方法
新式類中的屬性有三種訪問方式,并分別對應了三個被@property、@方法名.setter、@方法名.deleter修飾的方法
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。