Python之面向對象編程

面向對象編程中最重要的一個概念也就是類和對象。因此下面來介紹一下類的相關內容python

#類和對象編程

類是抽象的模板,好比咱們抽象一個學生類,很容易想到學生固有的一些屬性,好比名字,年齡等等,建立一個學生類:bash

class Student(object):
	pass
複製代碼

這裏的object是代表Student類是從哪一個類繼承來的,在python中object是全部類的父類(繼承的概念下文會說起)函數

建立實例對象tom:ui

tom = Student()
//咱們能夠自由地給類綁定屬性:
tom.name = 'XiaoMing'
tom.age = 23
複製代碼

那麼既然類具備模板的做用,因此咱們能夠把一些屬性強行綁定給類spa

class  NewStudent(object):
    def init(self,name,age):
    	self.name = name
    	self.age = age
複製代碼

這裏須要注意一點__init__方法的第一個參數永遠是self,表示建立的實例自己,所以,在__init__方法內部能夠把各類屬性綁定到self。有了__init__方法,在建立實例的時候就不能傳入空的參數了,必須傳入與__init__方法匹配的參數,可是self不須要傳,python解釋器會本身把實例變量傳進去。設計

咱們能夠給類添加打印學生信息的方法,把邏輯放在類內部,外部只須要調用便可:code

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(),咱們就能夠直接操做一個對象的狀態。

#最後 面向對象其實有不少知識點能夠寫,我只是作一個摘要而已,但願本身能堅持下去吧~

相關文章
相關標籤/搜索