1. 程式人生 > >Inheritance Of Python 類的繼承

Inheritance Of Python 類的繼承

python inheritance 繼承

Inheritance OOP三要素之一,繼承

人類和貓都繼承自動物類。

個體繼承自父母,集成了父母的一部分特征。

在面向對象的世界中,從父類繼承,就可以直接擁有弗雷德屬性和方法,這樣可以減少代碼,多復用。子類可以定義自己的屬性和方法。

類的繼承

對於python來講,所有的祖先都是object,所有的類都繼承自object

class Animal:

def __init__(self, name):

self._name = name

@property

def name(self):

return self._name

def shout(self

):

print(‘Animal shout‘)

class Cat(Animal):# 子類繼承父類

def shout(self):

print(‘miao‘) # override

class Persian(Cat): #看一下__dict就知道繼承了什麽屬性

def __init__(self):

self.eyes = ‘blue‘

class Dog(Animal):

def run(self):

print(‘Dog run‘)

tom = Cat(‘tom‘)

print(tom.name)

print(tom.__dict__

)

dog = Dog(‘ahuan‘)

print(dog.name)

dog.shout()

ani = Animal(‘monster‘)

ani.shout()

cat = Cat(‘garfield‘)

cat.shout()

print(cat.name)

tom

{‘_name‘: ‘tom‘}

ahuan

Animal shout

Animal shout

miao

garfield

增加了代碼的復用,減少了冗余。

有自己的特點,先繼承,再覆蓋

從上面的例子看出,通過繼承,子類不用寫代碼,直接繼承了父類的屬性和方法。

Inheritance

Superclass父類,fatherclass ,基類

childclass ,派生類

object類,python2.2之後引入的,它是所有類的共同祖先類。

Python2 中為了兼容,分為古典類和新式類。

python3之後都是是新式類

新式類都是繼承自object的,新式類可以使用super。

父類的就是你的,傳什麽就是什麽,如self。

實例繼承的屬性,放在實例類的實例上,即實例的一定放在實例上。只是self.的。類的放在類屬性上。

私有的都是不可訪問的

多繼承

OCP原則:多繼承、少修改

繼承的用途:增強基類、實現多態

多態:

在OOP中,superclass和childclass是通過繼承聯系在一起,如果通過一套方法,實現不同表現就是多態。

一個類繼承自多個類就是多繼承,它將具有多個類的特征。

多繼承的弊端

帶來路徑選擇問題,究竟繼承哪個superclass的feature

MRO(method resolution order)

Python 使用MRO解決基類搜索順序問題。

解決base class 搜索順序

MRO三種resolution order

技術分享

classic,從左到右,深度優先策略。2.2之前是MyClass,D,B,A,C,A

新式類,重復的只保留最後一個。MyClass,D,B,C,A,object

C3算法,在類被創建出來的時候,就計算出一個MRO有序列表。.MRO,返回一個有序列表。解決了多繼承的二義性。

lst = MyClass,D,B,C,A,object

多繼承的缺點

類很多,繼承復雜,繼承路徑太多,很難說清什麽樣的繼承路徑,語法允許多繼承,但解釋執行時執行時候才發現錯誤。

團隊協作開發,如果引入多繼承,代碼不可控。

不論是否支持多繼承,都應當避免多繼承。

Python的面向對象,太靈活,太開放,註重規矩。

增加需求

不完整的一個類,臨時使用,用上多繼承的方法,組合

新建一個需要的子類,可以增加和覆蓋原有不便的方法,這時候實例是子類的實例。

需求:

為Document子類提供打印能力

思路:

1、在Document中提供print方法

基類提供的方法不應該具體實現,子類需要覆蓋重寫。print算是一種能力,不是所有的Document子類都需要。

2、需要打印的子類上增加

繼承後增加,不用在子類上直接增加,遵循了OCP原則。但是如果遇到需要不確定的多項功能時,需要增加的子類過多。

3、裝飾器

printable相當於把PrintableWord的名字,即這個標示符拿去,就是拿了這個類(函數)對象,作為參數放到printable函數裏。給它添加了一個print方法(類對象是可以動態增加類屬性的)(數據的叫屬性,非數據的叫方法),類對象的__dict,類本身沒有變化。

運行時類對象與print函數綁定,將類對象作為第一參數傳入。

class Printable:

def _print(self):

print(self.content)

class Document:

def __init__(self, content):

self.content = content

class Word(Document): pass

class Pdf(Document): pass

def printable(cls):

cls.print = lambda self: print(self.content)

return cls

@printable # PrintableWord=printable(PrintableWrod)

class PrintableWord(Wrod): pass

在需要的地方動態增加,直接使用裝飾器,不需要對類進行修改。

Mixin

原則:Mixin應當覆蓋或替換類的功能,在繼承列表的最左邊。

class PrintableMxixin:

def print(self):

print(‘--------------------------‘)

print(‘{}‘.format(self.content))

print(‘--------------------------‘)

class Document:

def __init__(self, content):

self.content = content

def print(self):

print(self.content)

class Word(Document): pass

class PrintableWord(Word):pass

class Pdf(Document): pass

class PrintablePdf(PrintableMxixin, Pdf): 如果將Mixin放在右邊則改變了mro,使用Document的print方法。

pass

print(PrintablePdf.mro())

pdf = PrintablePdf(‘teset\nabc‘)

print(pdf.__dict__)

pdf.print()

[<class ‘__main__.PrintablePdf‘>, <class ‘__main__.PrintableMxixin‘>, <class ‘__main__.Pdf‘>, <class ‘__main__.Document‘>, <class ‘object‘>]

{‘content‘: ‘teset\nabc‘}

--------------------------

teset

abc

--------------------------

Mixin就是其他類混合進來,同時帶來了類的屬性和方法。

Mixin是類,可以繼承。

Mixin類的使用原則

  • Mixin類中不應該顯示的出現__init__初始化方法

  • Mixin類通常不能獨立工作,因為它是準備混入別的類中的部分功能實現

  • Mixin類的祖先類也應該是Mixin類


Inheritance Of Python 類的繼承