1. 程式人生 > >面向對象的成員與嵌套

面向對象的成員與嵌套

self. bubuko 限制 成員 傳參數 cme pre __init__ str

成員:

技術分享圖片

一.變量

  變量包括:實例變量(字段)和類變量(靜態字段),在定義和使用中有區別,本質區別是內存中保存的位置不同.(實例變量保存在對象中,類變量保存在類中.)

class Provice:
    country = ‘中國‘          #類變量
    def __init__(self, name):
        self.name = name      #實例變量
# 訪問實例變量,通過對象
obj = Provice(‘北京市‘)
print(obj.name)
#訪問類變量,通過類
print(Provice.country)
結果:
北京市
中國

實例變量與類變量的內存位置:技術分享圖片

   類變量在內存中只保存一份

   實例變量在每個對象中都保存一份

 應用場景: 通過類創建對象時,如果每個對象都具有相同的字段,那麽就使用靜態字段.

二.方法

  方法包括:普通方法,靜態方法,類方法.三種方法在內存中都在類中,區別在於定義和調用方式不同.

  普通方法: 由對象調用,至少有一個self參數,執行普通方法時,自動調用該方法的對象賦值給self.

  靜態方法: 由類調用,定義時在方法上面寫@staticmethod,無默認參數.

  類方法: 由類調用,定義時在方法上面寫@classmethod,至少有一個cls參數,執行類方法時,自動調用該方法的類復制給cls.

class Foo:
    def func(self):         #至少有一個self參數
        print(‘普通方法‘)
    @classmethod
    def func1(cls):         #至少有一個cls參數
        print(‘類方法‘)
    @staticmethod
    def func2():            #可以沒有參數
        print(‘靜態方法‘)
obj = Foo()                 #實例化一個對象
obj.func()                  #通過對象調用普通方法
obj.func1()                 #可以通過對象調用類方法,一般不建議用
obj.func2()                 #可以通過對象調用靜態方法,一般不建議用

Foo.func1()                 #通過類調用類方法
Foo.func2()                 #通過類調用靜態方法
結果:
普通方法
類方法
靜態方法

類方法
靜態方法

  相同點: 所有的方法,都屬於類中,在內存中只保存一份.

  不同點: 方法的定義不同,調用時自動傳入的參數不同.

  靜態方法的使用: 如果方法無需使用對象中封裝的值,就可以使用靜態方法.

三.屬性

  屬性是普通方法的變種

class Foo:
def func(self):
print(‘普通方法‘)
@property #定義屬性時,方法上面加@property
def func1(self): #屬性定義時,只有一個self參數,不能加參數
return ‘屬性‘

obj = Foo()
obj.func() #普通方法調用時,需要加括號
ret = obj.func1 #屬性調用時,無需加括號
print(ret)
結果: 
普通方法
屬性

  屬性存在的意義是調用的時候不需要加括號.

  屬性的應用場景: 類中的方法,既不需要傳參數且有返回結果.可以使用@property.

類的成員修飾符

  每一個類的成員都有兩種形式: 公有成員, 私有成員

  公有成員: 在任何地方都能訪問

  私有成員:只有在類的內部可以訪問

  公有成員與私有成員的定義不同:私有成員命名時,前兩個字符是下劃線.(__init__等特殊成員除外)

class Foo:
    def __init__(self):
        self.name = ‘公有字段‘
        self.__foo = ‘私有字段‘
    def per(self):
        print(self.__foo)
obj = Foo()
print(obj.name)
obj.per()
print(obj.__foo)
結果:
公有字段
私有字段
報錯

  公有成員與私有成員的訪問限制不同:

  字段:

    公有字段:對象可以訪問,類內部可以訪問,派生類也可以訪問.

    私有字段:只有類內部可以訪問.

技術分享圖片
class Foo:
    def __init__(self):
        self.foo = 公有字段
    def func(self):
        print(self.foo)         #類內部訪問
class Foo1(Foo):
    def show(self):
        print(self.foo)         #派生類訪問
obj = Foo()
print(obj.foo)                  #通過對象訪問
obj.func()                      #類內部訪問

obj1 = Foo1()
obj1.show()                     #派生類訪問
結果:
公有字段
公有字段
公有字段
公有字段 技術分享圖片
class Foo:
    def __init__(self):
        self.__foo = 私有字段
    def func(self):
        print(self.__foo)           #類內部訪問
class Foo1(Foo):
    def show(self):
        print(self.__foo)           #派生類訪問
    def per(self):
        self.func()
obj = Foo()
obj.func()                          #類內部訪問==>正確
# print(obj.__foo)                    #通過對象訪問==>錯誤

obj1 = Foo1()
# obj1.show()                         #派生類訪問==>錯誤
obj1.per()                               #派生類通過基類內部訪問==>正確.
                                              #實質是通過類內部訪問       
私有字段

  靜態字段:

    公有靜態字段:類可以訪問,類內部可以訪問,派生類可以訪問

    私有靜態字段:只有類內部可以訪問.

技術分享圖片
class Foo:
    name = 公有靜態字段
    def func(self):
        print(Foo.name)
class Foo1(Foo):
    def show(self):
        print(Foo.name)

print(Foo.name)             #類訪問

obj = Foo()
obj.func()                  #類內部可以訪問

obj1 = Foo1()
obj1.show()                 #派生類中可以訪問
結果:
公有靜態字段
公有靜態字段
公有靜態字段
公有靜態字段 技術分享圖片
class Foo:
    __name = 私有靜態字段
    def func(self):
        print(Foo.__name)
class Foo1(Foo):
    def show(self):
        print(Foo.__name)
    def per(self):
        self.func()
print(Foo.__name)          #類訪問==>錯誤

obj = Foo()
obj.func()                 #類內部訪問==>正確

obj1 = Foo1()
obj1.show()                #派生類中訪問==>錯誤

obj1.func()                #派生類通過基類內部訪問==>正確
私有靜態字段

  方法,屬性的成員修飾符與上述方式相似.私有成員只能在類內部使用.

  註意:如果非要訪問私有屬性,可以通過對象._類__屬性名

面向對象的成員與嵌套