Python學習系列 - 面向對象編程(六)

面向對象

面向對象編程——Object Oriented Programming,簡稱OOP,是一種程序設計思想。OOP把對象做爲程序的基本單元,一個對象包含了數據和操做數據的函數python

類和實例

這是面向對象最重要的概念,就是將面向對象的概念具象化。
這裏咱們先定義一條狗,狗要有姓名和年齡。編程

# 咱們在這裏定義一個狗的類
class Dog(object):  
    # __init__ 爲初始化方法
    def __init__(self, name, age):  
        self.name = name  
        self.age = age
    # 咱們再寫一個方法,打印狗的名字和年齡
    def print_dog(self):  
        print('%s: %s' % (self.name, self.age))

接下來咱們就調用一下這個類函數

# 咱們首先先給dog賦值,名字和年齡
dog = Dog("小花", 12) 
# 調用咱們以前寫的打印方法
dog.print_dog()
運行結果:
小花: 12

這樣咱們就簡單的將狗進行了數據封裝,咱們只須要知道咱們在建立狗的實例變量的時候須要傳名字和年齡就能夠了。
而後咱們還能夠在裏面增長方法,並且咱們在調用方法的時候根本不去關心內部的運行原理。設計

訪問限制

在Class內部,能夠有屬性和方法,而外部代碼能夠調用。這樣就能夠很好的隱藏了內部的實現邏輯。
但是,上面的代碼中,外部仍是能夠自由的修改實例中的屬性值。
咱們但願內部屬性不能被外部修改的話,咱們就能夠在屬性名稱前加上兩個下劃線__
在Python中,實例的變量名若是以__開頭,就變成了一個私有變量(private),只有內部能夠訪問,外部不能訪問。code

class Dog(object):  
    def __init__(self, name, age):  
        self.__name = name  
        self.__age = age  

    def print_dog(self):  
        print('%s: %s' % (self.__name, self.__age))

咱們這邊運行一下:對象

dog = Dog("小花", 12)  
dog.print_dog()  
print(dog.__name)
運行結果:
小花: 12
Traceback (most recent call last):
File "D:/WorkSpace/python/test.py", line 12, in <module>
print(dog.__name)
AttributeError: 'Dog' object has no attribute '__name'

不過若是咱們須要對內部的值進行修改的話怎麼辦呢?這裏咱們能夠新建方法,get_name和set_name。繼承

class Dog(object):  
    def __init__(self, name, age):  
        self.__name = name  
        self.__age = age  

    def print_dog(self):  
        print('%s: %s' % (self.__name, self.__age))

    # 獲取__name
    def get_name(self):
        return self.__name

    # 給__name賦值
    def set_name(self, name):
        self.__name = name

這裏咱們再運行一下:字符串

dog = Dog("小花", 12)  
dog.print_dog()  
print(dog.get_name())
運行結果:
小花: 12
小花
  • 在Python中,變量名相似__xxx__的,也就是以雙下劃線開頭,而且以雙下劃線結尾的,是特殊變量,特殊變量是能夠直接訪問的,不是private變量。
  • 以一個下劃線開頭的實例變量名,好比_name,這樣的實例變量外部是能夠訪問的,可是,這樣的變量意思是告訴你請不要隨便訪問我,我是私有變量。

繼承和多態

在OOP程序設計中,當咱們定義一個新class的時候,能夠從已有的class繼承,新的class稱爲子類(Subclass),而被繼承的class稱爲基類、父類或超類(Base class、Super class)。get

class People(object):
    def drink(self):
        print('People are drinking water')

class Chinese(People):
    pass

class Japanese(People):
    pass

咱們這邊調用運行一下:it

chinese = Chinese()  
chinese.drink()  
  
japanese = Japanese()  
japanese.drink()
運行結果:
People are drinking water
People are drinking water

這裏能夠看出來,因爲People有drink方法,他的子類Chinese和Japanese什麼都沒有作,就繼承了drink方法。

獲取對象信息

1、使用type()函數

使用type()函數,能夠獲取任何數據的類型。若是要判斷一個數據是否是函數,可使用types模塊中定義的常量,如:types.FunctionType、types.LambdaType。

2、使用isinstance()函數

isinstance函數判斷的是一個對象是不是該類型或位於該類型的父類繼承鏈上。isinstance還能夠判斷一個變量是不是某些類型的一種,用元組寫多種類型。

3、使用dir()函數

1.若是要得到一個對象所有的屬性和方法,可使用dir()函數。它返回一個包含 字符串的list。

2.相似「__xxx__」的屬性和方法在Python中都是有特殊用途的,好比len()函數獲取對象的長度。但實際上,在len函數內部它會去自動調用對象的__len__()方法,因此,你能夠在類中本身設定一個__len__()方法,讓len返回你想要返回的長度。

4、操做一個對象狀態

如getattr() 獲取、setattr() 設置 和hasattr() 有沒有 方法,能夠直接操做一個對象的狀態。

hasattr(obj,'x') #有屬性‘x’嗎?
setattr(obj,'y',18) #設置一個屬性‘y’,值爲18.
getattr(obj,'y') #獲取屬性y
getattr(obj,'z',404) #獲取屬性z,若是不存在,就返回默認值404.

實例屬性和類屬性

實例屬性屬於各個實例全部,互不干擾;類屬性屬於類全部,全部實例共享一個屬性;不要對實例屬性和類屬性使用相同的名字,不然將產生難以發現的錯誤。

相關文章
相關標籤/搜索