跟老齊學Python之編寫類之三子類

來源:互聯網
上載者:User
關於類,看官想必已經有了感覺,看下面的代碼,請仔細閱讀,並看看是否能夠發現點什麼問題呢?
複製代碼 代碼如下:


#!/usr/bin/env python
#coding:utf-8

class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email

def author(self):
return self.name

class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list

if __name__=="__main__":
writer = Person("qiwsir","Chinese","qiwsir@gmail.com")
python = Programmer("qiwsir","Python","qiwsir@gmail.com","Ubutun","qiwsir.github.io")
print "My name is:%s"%writer.author()
print "I write program by:%s"%python.pythoner()[1]

上面這段代碼,運行起來沒有什麼問題,但是,仔細看,發現有兩個類,一個名字叫做Person,另外一個叫做Programmer,這還不是問題所在,問題所在是這兩個類的建構函式中,存在這相同的地方:self.name=name,self.lang=lang,self.email=email,這對於追求代碼品質的程式員,一般是不允許的。最好不要有重複代碼或者冗餘代碼。可是,在兩個類中都要有這些參數,應該怎麼辦呢?

子類、父類和繼承

看下面的代碼,裡面有兩個類A,B。這段程式能夠正確運行,每個類的功能是僅僅列印指定的內容。
複製代碼 代碼如下:


#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print "aaa"

class B:
def __init__(self):
print "bbb"

if __name__=="__main__":
a = A()
b = B()

#運行結果
aaa
bbb

上面的兩個類彼此之間沒有所謂的父子關係。現在稍加改變,將類B改寫,注意觀察與上面的差異。
複製代碼 代碼如下:

#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print "aaa"

class B(A): #這裡和上面程式不同。B繼承了A
def __init__(self):
print "bbb"

if __name__=="__main__":
a = A()
b = B()

#運行結果
aaa
bbb

這段程式中,類B跟前面的那段有一點不同,class B(A):,這樣寫就表明了B相對A的關係:B是A的子類,B從A繼承A的所有東西(子承父業)。

但是,看官發現了沒有,運行結果一樣。是的,那是以為在B中儘管繼承了A,但是沒有調用任何A的東西,就好比兒子從老爸那裡繼承了財富,但是兒子一個子也沒動,外界看到的和沒有繼承一樣。
複製代碼 代碼如下:


#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print "aaa"

class B(A):
def __init__(self):
#print "bbb"
A.__init__(self) #運行繼承的父類

if __name__=="__main__":
a = A()
b = B()

#運行結果
aaa
aaa

這回運行結果有了變化,本來b=B()是運行類B,但是B繼承了A,並且在初始化的建構函式中,引入A的建構函式,所以,就運行A的結果相應結果了。

下面把最開頭的那端程式用子類繼承的方式重寫,可以是這樣的:
複製代碼 代碼如下:


#!/usr/bin/env python
#coding:utf-8

class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email

def author(self):
return self.name
"""
class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list
"""

class Programmer(Person): #繼承父類Person
def __init__(self, name, lang, email, system, website):
Person.__init__(self,name,lang,email) #將Person.__init__()的功能繼承到這裡
#self.name = name #這三句是Person中已經搞定的,就不用重複
#self.lang = lang #通過繼承已經實現了這三句的功能
#self.email = email
self.system = system #子類中不同於Person父類部分
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list

if __name__=="__main__":
writer = Person("qiwsir","Chinese","qiwsir@gmail.com")
python = Programmer("qiwsir","Python","qiwsir@gmail.com","Ubutun","qiwsir.github.io")
print "My name is:%s"%writer.author()
print "I write program by:%s"%python.pythoner()[1]

代碼運行結果與前面一樣。

列位是否理解了子類和父類、繼承的特點。如果你有一個老爹,是一個高官或者富豪,那麼你就官二代或者富二代了,你就從他們那裡繼承了很多財富,所以生活就不用太勞累了。這就是繼承的作用。在代碼中,也類似,繼承能夠讓寫代碼的少勞累一些。

對於為什麼要用繼承,好友@令狐蟲 大俠給了以非常精彩的解釋:

複製代碼 代碼如下:


從技術上說,OOP裡,繼承最主要的用途是實現多 態。對於多態而言,重要的是介面繼承性,屬性和行為是否存在繼承性,這是不一定的。事實上,大量工程實踐表明,重度的行為繼承會導致系統過度複雜和臃腫, 反而會降低靈活性。因此現在比較提倡的是基於介面的輕度繼承理念。這種模型裡因為父類(介面類)完全沒有代碼,因此根本談不上什麼代碼複用了。

在Python裡,因為存在Duck Type,介面定義的重要性大大的降低,繼承的作用也進一步的被削弱了。

另外,從邏輯上說,繼承的目的也不是為了複用代碼,而是為了理順關係。


我表示完全贊同上述解釋。不過看官如果不理解,也沒有關係,上述解釋中的精神,的確需要在編程實踐中感悟才能領會到的。
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.