1. 程式人生 > >python學習31(面向對象)

python學習31(面向對象)

外部類 刪除 基類 pla 種類 property object 個數 訪問類

類的兩種類型:
經典類:
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修飾的方法

python學習31(面向對象)