Python學習之單繼承與多繼承


  1. 繼承

面向對象編程語言的一個主要功能就是“繼承”。

繼承是指這樣一種能力:它可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴展。

(1) 單繼承python同時支持類的繼承。如果一種語言不支持繼承,類就沒什么意義。

類還允許派生,即用戶可以創建一個子類,它也是類,而且繼承父類(即基類)的所有特征和屬性。

創建派生類的語法格式為:

class DerivedClassName(BaseClassName):

    <statement-1>

    ...

    <statement-N>

基類名BaseClassName必須與派生類定義在一個作用域內。除了用類名,還可以用表達式。

例如:單繼承舉例:

class people:

#定義基本屬性

    name=''    

age=0

#定義私有屬性,私有屬性在類外部無法直接進行訪問

__weight=0

#定義構造方法

    def __init__(self,n,a,w):

        self.name=n

        self.age=a

        self.__weight=w

    def speak(self):

        print("%s says:I am %d years old"%(self.name,self.age))

#單繼承

class student(people):

grade=''

#調用父類的構造函數

    def __init__(self,n,a,w,g):

        people.__init__(self,n,a,w)   #student繼承並使用people的__init__函數

        self.grade=g                   #不同於people的參數g

#重寫父類的方法

def speak(self):

#顯示student的信息

        print("%s says:I am %d years old,I am in Grade %d."%(self.name,self.age,self.grade))

s=student('Tom',10,90,3)        #實例化student類

s.speak()                        #顯示student的speak方法

#運行結果:Tom says:I am 10 years old,I am in Grade 3.

 

 

(2) 多繼承:某個類繼承了多個父類

多繼承的類定義語法格式如下:

class DerivedClassName(Base1,Base2,Base3):

    <statement-1>

    ...

<statament-N>

#注意解析類屬性的規則是,順序是深度優先,從左到右。因此,如果在DerivedClassName(示例中的派生類)中沒有找到這個屬性,就會搜索Base1,然后遞歸的搜索其基類,如果最終沒有找到,就搜索Base2,依次類推。深度優先不區分屬性繼承自基類還是直接定義。

例如:class people:

#定義基本屬性

    name=''    

    age=0

    __weight=0

#定義構造方法

    def __init__(self,n,a,w):

        self.name=n

        self.age=a

        self.__weight=w

    def speak(self):

        print("%s says:I am %d years old"%(self.name,self.age))

#單繼承

class student(people):

    grade=''

#調用父類的構造函數

    def __init__(self,n,a,w,g):

        people.__init__(self,n,a,w)   #student繼承並使用people的__init__函數

        self.grade=g

        def speak(self):

        print("%s says:I am %d years old,I am in Grade %d."%(self.name,self.age,self.grade))

class speaker():

    topic=''

    name=''

    def __init__(self,n,t):

        self.name=n

        self.topic=t

    def speak(self):

        print("I am %s,I am a speaker,my topic is %s"%(self.name,self.topic))

        

class sample(speaker,student):

    a=''

    def __init__(self,n,a,w,g,t):

        student.__init__(self,n,a,w,g)

        speaker.__init__(self,n,t)

test_1=sample("Tom",12,90,3,"One World One Dream")

test_1.speak()

#執行結果:I am Tom,I am a speaker,my topic is one World One Dream.

(3) 補充

1.方法重寫

如果父類方法的功能不能滿足需求,可以在子類里重寫父類的方法。

例如:

class Parent:               #定義父類

    def myMethod(self):

        print('調用父類方法')

class Child(Parent):          #定義子類

    def myMethod(self):

        print('調用子類方法')

Child_1=Child()                     #子類實例

Child_1.myMethod()                      #子類調用重寫方法

輸出:調用子類方法

2. if__name__=’__main__’的作用

這條語句的意思是,讓程序員寫的腳本模塊既可以導入到別的模塊中調用,也可以在模塊中自己執行。

例如 #y1htext.py

def main():

    print('hello world,I am in %s now.' %__name__)

if __name__=='__main__':

main()                      運行結果:hello world,I am in __main__now.

在這個文件中定義了一個main()函數,如果執行該.py文件,則if語句中的內容被執行,成功調用main()函數。

從另一個模塊導入該模塊,這個模塊的名字是test1.py

#test1.py

from y1htext import main

mian()         #相同的運行結果

3. 運算符重載:用於新類的運算符的實現。

運算符重載是針對新類型數據的實際需要,對原有運算符進行適當的改造,一般來說,重載的功能應當與原有功能相類似,不能改變原運算符的操作對象個數,同時至少要有一個操作對象是自定義類型。

Python支持運算符重載,它的運算符重載就是通過重寫這些python內建方法來實現的。這些內建方法都是以雙下划線開頭和結尾的,Python通過這種特殊的命名方式來攔截操作符,以實現重載。

例如:+用__add__方法,+=用__iadd__方法,...,*用__mul__方法等

Python的內置操作運用於類對象時,Python會去搜索並調用對象中指定的方法來完成操作。運算符重載是通過創建運算符函數實現的,運算符重載實際是一個函數,所以運算符的重載實際上是函數的重載。

例如:運算符重載

class Computation():

    def __init__(self,value):

        self.value=value

    def __add__(self,other):

        return(self.value+other.value)

    def __sub__(self,other):

        return(self.value-other.value)

c1=Computation(10)

c2=Computation(10)

print(c1+c2)

print(c1-c2)  #“-”在作用於類對象,實現減法運算符的重載

說明:如果類實現了__add__的方法,當類的對象出現在“+”運算符中時,會調用這個方法;如果類實現了__sub__方法,當類的對象出現在“-”運算符中時,會調用這個方法。重載這兩個方法就是可以在普通的類對象上添加“+”和“-”運算。

 

 

(4) isinstance函數(Python語言的一個內建函數)

語法:isinstance(object,type) 函數是Python語言的一個內建函數

作用是:判斷一個對象或者變量是否是一個已知的類型。

 針對類來說如果參數是object是type類的實例(判斷一個對象是否為該類的實例)或者object是type類的子類的一個實例,則返回True.如果object不是一個給定類型的對象,則返回結果是False.

class objA:

    pass

class objB(objA):

    pass

A=objA()

B=objB()

print(isinstance(A,objA))

print(isinstance(B,objA))

print(isinstance(A,objB))           

print(isinstance(B,objB))

② 針對變量來說,第一個參數(object)為變量,第二個參數(type)為類型名或者由變量名組成的一個元組(如(int,list,float)),其返回值為布爾型(Ture或False).若第一個參數為一個元組,則變量類型與元組類型名之一相同時即返回True.

a=2

print(isinstance(a,int))

print(isinstance(a,str))

print(isinstance(a,(str,int,list)))

(5) super()函數

當存在繼承關系的時候,有時候需要在子類中調用父類的方法。如果修改父類名稱,那么在子類中會涉及多處修改。

Python引入了super()機制,語法格式如下:

super(type[,object-or-type])

例如:

class A(object):

    def __init__(self):

        print('enter A')

        print('leave A')

class BA.:    #B繼承A

    def __init__(self):

        print("enter B")

        super(B,self).__init__()   #python2對其理解為:super(B,self)首先找到B的父類(就是類A),然后把類B的對象self轉換為類A的對象,然后被轉換的類A對象調用自己的__init__函數。Python3.x可以不加參數而直接寫為super().__init__,並且可以像父類中的屬性賦值。

        print("leave B")

b=B()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM