物件導向程式設計中最重要的一個概念也就是類和物件。所以下面來介紹一下類的相關內容
#類和物件
類是抽象的模板,比如我們抽象一個學生類,很容易想到學生固有的一些屬性,比如名字,年齡等等,建立一個學生類:
class Student(object):
pass
複製程式碼
這裡的object是表明Student類是從哪個類繼承來的,在python中object是所有類的父類(繼承的概念下文會提及)
建立例項物件tom:
tom = Student()
//我們可以自由地給類繫結屬性:
tom.name = 'XiaoMing'
tom.age = 23
複製程式碼
那麼既然類具有模板的作用,所以我們可以把一些屬性強行繫結給類
class NewStudent(object):
def init(self,name,age):
self.name = name
self.age = age
複製程式碼
這裡需要注意一點__init__方法的第一個引數永遠是self,表示建立的例項本身,因此,在__init__方法內部可以把各種屬性繫結到self。有了__init__方法,在建立例項的時候就不能傳入空的引數了,必須傳入與__init__方法匹配的引數,但是self不需要傳,python直譯器會自己把例項變數傳進去。
我們可以給類新增列印學生資訊的方法,把邏輯放在類內部,外部只需要呼叫即可:
class NewStudent(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def printInfo(self):
print('name:%s,age:%s'%(self.__name,self.__age))
john = NewStudent('JOHN',32)
//類外部呼叫:
john.printInfo()
複製程式碼
#訪問限制 在上面的程式碼中,我們雖然把屬性方法寫在了類的內部,實際上,我們從外面還是能夠對他進行修改的,python中在屬性的名字前面加雙下劃線就使屬性變成了私有,外部不能訪問也不可更改。
class NewStudent(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
複製程式碼
如果我們有想要獲取想要更改怎麼辦呢?可以通過get set方法:
class NewStudent(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def printInfo(self):
print('name:%s,age:%s'%(self.__name,self.__age))
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def set_name(self,name):
self.__name = name
def set_age(self,age):
self.__age = age
john.set_name('HAHA')
john.set_age(10)
print(john.get_name())
print(john.get_age())
複製程式碼
至於為什麼這麼折騰呢?寫成私有變數的好處就是我允許外部訪問或修改,但是我內部是有判斷的。
#繼承和多型 在OOP程式設計中,我們定義一個類的時候,可以從現有的類繼承;新的類就稱為子類,而被繼承的類就是父類,基類或超類。
class Animal(object):
def run(self):
print('Animal is running...')
def eat(self):
print('Animal is eating...')
class Dog(Animal):
pass
class Cat(Animal):
pass
複製程式碼
上面的三個類,Animal就是Dog和Cat的父類,那麼繼承有什麼好處呢?
dog = Dog()
cat = Cat()
dog.run()
cat.run()
//Animal is running...
//Animal is running...
複製程式碼
從上面的程式碼可以看出,子類繼承了父類的全部方法(功能);
當然子類也可以擁有自己的方法:
class Animal(object):
def run(self):
print('Animal is running...')
def eat(self):
print('Animal is eating...')
class Dog(Animal):
def run(self):
print('Dog is running...')
def bark(self):
print('Dog is barking...')
class Cat(Animal):
def run(self):
print('Cat is running...')
def jump(self):
print('Cat is jumping...')
dog = Dog()
cat = Cat()
dog.run()
dog.eat()
dog.bark()
cat.run()
cat.eat()
cat.jump()
複製程式碼
繼承還有一個好處就是,子類可以對父類的方法進行重寫,當子類和父類都有同樣的方法時,子類會覆蓋父類的方法,這就是繼承的另一個好處:多型。
多型其實講了一個現實生活很常見的現象,那就是狗是動物,貓也是動物,但是動物不是狗,動物也不是貓;繼承導致了Dog和Cat類有了兩種型別,這是一個很重要的功能
比如我們定義一個方法:
def run_twice(animal):
animal.run()
animal.run()
run_twice(Animal())
複製程式碼
當我們傳入Animal例項就會執行兩次run方法
run_twice(Dog())
run_twice(Cat())
複製程式碼
當我們傳入子類物件的時候,子類物件也會執行兩次類方法
#獲取物件資訊 當我們拿到一個物件的引用,如何知道這個物件是什麼型別有什麼方法?
##使用type()
print(type(123) == int)
print(type('123') == str)
複製程式碼
判斷基本型別可以直接寫int,str,但是如果要判斷物件是不是函式呢?
import types
def function():
pass
print(type(function) == types.FunctionType)
print(type(lambda x: x*x) == types.LambdaType)
print(type((x for x in range(10)))==types.GeneratorType)
print(type(abs)==types.BuiltinFunctionType)
複製程式碼
##使用isinstance()
a = Animal()
d = Dog()
c = Cat()
print(isinstance(a,Animal))
print(isinstance(d,Animal))
print(isinstance(d,Dog))
複製程式碼
##使用dir() dir()返回一個包含字串的list
dir('123')
//可以獲取str物件的所有屬性和方法
複製程式碼
類似__XXX__的屬性和方法在python中都是有特殊用途的,比如__len__方法返回長度。在Python中,如果你呼叫len()函式試圖獲取一個物件的長度,實際上,在len()函式內部,它自動去呼叫該物件的__len__()方法,所以,下面的程式碼是等價的:
len('123')
'123'.__len__()
//執行結果:
//3
複製程式碼
淡然僅僅把屬性和方法列出來是不夠的,還有配合getattr()、setattr()以及hasattr(),我們就可以直接操作一個物件的狀態。
#最後 物件導向其實有很多知識點可以寫,我只是做一個摘要而已,希望自己能堅持下去吧~