首頁 後端開發 Python教學 一文了解什麼是Python物件導向中的繼承

一文了解什麼是Python物件導向中的繼承

Aug 28, 2019 pm 05:40 PM
python 繼承 物件導向

一文了解什麼是Python物件導向中的繼承

1、什麼是繼承?

繼承指的是類別與類別之間的關係,是一種什麼是什麼的關係,功能之一就是用來解決程式碼重複使用問題。

繼承是一種建立新類別的方式,在python中,新建的類別可以繼承一個或多個父類,父類又可稱為基底類別或超類,新建的類別稱為派生類或子類,繼承又分為單繼承和多繼承。

class ParentClass1: #定义父类
    pass
class ParentClass2: #定义父类
    pass
class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass
class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass
print(Son1.__bases__)  # 查看所有继承的父类
print(Son2.__bases__)
===============
(<class &#39;__main__.Father1&#39;>,)
(<class &#39;__main__.Father1&#39;>, <class &#39;__main__.Father2&#39;>)
登入後複製

2、繼承與抽象

抽象分成兩個層次:

1.將歐巴馬與梅西這兩個物件比較像的部分抽取成類別;

2.將人,豬,狗這三個類別比較像的部分抽取成父類別。

抽象最主要的作用是分割類別(可以隔離關注點,降低複雜度)

一文了解什麼是Python物件導向中的繼承

繼承:

一文了解什麼是Python物件導向中的繼承

#是基於抽象的結果,透過程式語言去實現它,肯定是先經歷抽象這個過程,才能透過繼承的方式去表達出抽象的結構。

抽像只是分析和設計的過程中,一個動作或是說一種技巧,透過抽象可以得到類別。

class animal():   # 定义父类
    country  =  &#39;china&#39;     # 这个叫类的变量
    def __init__(self,name,age):
        self.name=name   # 这些又叫数据属性
        self.age=age
    def walk(self):         # 类的函数,方法,动态属性
        print(&#39;%s is walking&#39;%self.name)
    def say(self):
        pass
class people(animal):  # 子类继承父类
    pass
class pig(animal):    # 子类继承父类
    pass
class dog(animal):  # 子类继承父类
    pass
aobama=people(&#39;aobama&#39;,60)   # 实例化一个对象
print(aobama.name)
aobama.walk()
===================
aobama
aobama is walking
登入後複製

3、派生

1.在父類別的基礎上產生子類,產生的子類別就叫做派生類。

2.父類別裡沒有的方法,在子類別中有了,這樣的方法就叫做衍生方法。

3.父類別裡有,子類別也有的方法,就叫做方法的重寫(就是把父類別裡的方法重寫了)。

相關推薦:《

Python影片教學

範例1

class Hero:
    def __init__(self, nickname,
                 aggressivity,
                 life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        enemy.life_value -= self.aggressivity
class Garen(Hero):   # 子类继承  hero 父类
    camp=&#39;Demacia&#39;   # 子类衍生出的变量
    def attack(self, enemy):   # 跟父类的 attack 重名,对象调用的时候以子类的为准
        pass
    def fire(self):    # 父类没有 fire,这里 fire 属于派生出来的东西
        print(&#39;%s is firing&#39; %self.nickname)
class Riven(Hero):
    camp=&#39;Noxus&#39;
g1=Garen(&#39;garen&#39;,18,200)
r1=Riven(&#39;rivren&#39;,18,200)
# print(g1.camp)
# print(r1.camp)
# g1.fire()
g1.attack(g1)
登入後複製
例2
class Hero:
    def __init__(self, nickname,aggressivity,life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        print(&#39;Hero attack&#39;)
class Garen(Hero):
    camp = &#39;Demacia&#39;
    def attack(self, enemy): #self=g1,enemy=r1
        # self.attack(enemy) #g1.attack(r1),这里相当于无限递归
        Hero.attack(self,enemy)  # 引用 父类的 attack,对象会去跑 父类的 attack
        print(&#39;from garen attack&#39;)  # 再回来这里
    def fire(self):
        print(&#39;%s is firing&#39; % self.nickname)
class Riven(Hero):
    camp = &#39;Noxus&#39;
g1 = Garen(&#39;garen&#39;, 18, 200)
r1 = Riven(&#39;rivren&#39;, 18, 200)
g1.attack(r1)
# print(g1.camp)
# print(r1.camp)
# g1.fire()
登入後複製

4、組合與重用性

重用性:

方式1:不透過繼承的方式重複使用屬性,指名道姓的使用哪個類別的屬性。

class Hero:
    def __init__(self,nickname,gongji,life):
        self.nickname=nickname
        self.gongji=gongji
        self.life=life
    def attack(self,obj):
        print(&#39;from Hero attack&#39;)
class Garen:
    def __init__(self,nickname,gongji,life,script):
        Hero.__init__(self,nickname,gongji,life)   # 这里引用Hero类的 init,不用再自己从新定义一遍 init
        self.script=script   # 父类 init 没有 script,这里是新加进来的属性
    def attack(self,obj):  # 在这里自己定义新的 attack,不再使用父类的 attack
        print(&#39;from Garen attack&#39;)
    def fire(self):  # 在这里定义新的功能
        print(&#39;from Garen fire&#39;)
g1=Garen(&#39;garen&#39;,18,200,&#39;人在塔在&#39;)
print(g1.script)
人在塔在
登入後複製

提示:用已經有的類別建立一個新的類,這樣就重用了已經有的軟體中的一部分甚至大部分,大大省了程式設計工作量,這就是常說的軟體重用,不僅可以重複使用自己的類,也可以繼承別人的,例如標準函式庫,來客製化新的資料類型,這樣就是大大縮短了軟體開發週期,對大型軟體開發來說,意義重大。

注意:像g1.life之類的屬性引用,會先從實例中找life,然後去類別中找,然後再去父類別中找...直到最頂級的父類別。

方式2:透過繼承

範例1

class Hero():
    def __init__(self, nickname, gongji, life):
        self.nickname = nickname
        self.gongji = gongji
        self.life = life
    def attack(self, obj):
        print(&#39;from Hero attack&#39;)
        obj.life -= self.gongji
class Garen(Hero):   # 使用 super方式需要继承
    camp = &#39;Demacia&#39;
    def __init__(self, nickname, gongji, life):
        super().__init__(nickname, gongji, life)
    def attack(self, obj):  # 在这里自己定义新的 attack,不再使用父类的 attack
        super(Garen, self).attack(obj)  # PY3中super可以不给参数,PY2中第一个参数必须是自己的类,self,可以使用
        父类的方法,方法需要给参数就给参数
    def fire(self):  # 在这里定义新的功能
        print(&#39;from Garen fire&#39;)
g1 = Garen(&#39;garen1&#39;, 18, 200)
g2 = Garen(&#39;garen2&#39;, 20, 100)
print(g2.life)
g1.attack(g2)
print(g2.life)
100
from Hero attack
82
登入後複製

範例2

class A:
    def f1(self):
        print(&#39;from A&#39;)
        super().f1()    
        # 这种不需要继承也可以使用到 super,为什么,要看 C的 MRO表
class B:
    def f1(self):
        print(&#39;from B&#39;)
class C(A,B):
    pass
print(C.mro())
#[<class &#39;__main__.C&#39;>,
# <class &#39;__main__.A&#39;>,
# <class &#39;__main__.B&#39;>, #  B在A的后面,当A指定 super().f1 会找到 B的 f1
# <class &#39;object&#39;>]
c=C()
c.f1()
登入後複製

組合:

軟體重用的重要方式除了繼承之外還有另一種方式,即:組合。

組合:一個物件的資料屬性是另一個對象,稱為組合。

class Equip: #武器装备类
    def fire(self):
        print(&#39;release Fire skill&#39;)
class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类
    camp=&#39;Noxus&#39;
    def __init__(self,nickname):
        self.nickname=nickname
        self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性
r1=Riven(&#39;锐雯雯&#39;)
r1.equip.fire() #可以使用组合的类产生的对象所持有的方法
release Fire skill
登入後複製

組合的方式:

組合與繼承都是有效地利用已有類別的資源的重要方式。但二者的概念和使用場景皆不同。

1.繼承的方式

透過繼承建立了衍生類別與基底類別之間的關係,它是一種'是'的關係,例如白馬是馬,人是動物。

當類別之間有很多相同的功能,提取這些共同的功能做成基類,用繼承比較好,比如老師是人,學生是人

2.組合的方式

用組合的方式建立了類與組合的類之間的關係,它是一種'有'的關係,比如教授有生日,教授教python和linux課程,教授有學生s1、s2 、s3...

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
class Course:
    def __init__(self,name,period,price):
        self.name=name
        self.period=period
        self.price=price
    def tell_info(self):
        print(&#39;<%s %s %s>&#39; %(self.name,self.period,self.price))
class Teacher(People):
    def __init__(self,name,age,sex,job_title):
        People.__init__(self,name,age,sex)
        self.job_title=job_title
        self.course=[]
        self.students=[]
class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)
        self.course=[]
egon=Teacher(&#39;egon&#39;,18,&#39;male&#39;,&#39;沙河霸道金牌讲师&#39;)
s1=Student(&#39;牛榴弹&#39;,18,&#39;female&#39;)
python=Course(&#39;python&#39;,&#39;3mons&#39;,3000.0)
linux=Course(&#39;python&#39;,&#39;3mons&#39;,3000.0)
#为老师egon和学生s1添加课程
egon.course.append(python)
egon.course.append(linux)
s1.course.append(python)
#为老师egon添加学生s1
egon.students.append(s1)
#使用
for obj in egon.course:
    obj.tell_info()
登入後複製

5、介面與歸一化設計

a、為何要用介面?

介面提取了一群類別共同的函數,可以把介面當作一個函數的集合。

然後讓子類別去實作介面中的函數。

這麼做的意義在於歸一化,什麼叫歸一化,就是只要是基於同一個介面實現的類,那麼所有的這些類產生的物件在使用時,從用法上來說都一樣。

歸一化的好處在於:

歸一化讓使用者不需要關心物件的類別是什麼,只需要的知道這些物件都具備某些功能就可以了,這極大地降低了使用者的使用難度。 ###
class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
    def read(self): #定接口函数read
        pass
    def write(self): #定义接口函数write
        pass
class Txt(Interface): #文本,具体实现read和write
    def read(self):
        print(&#39;文本数据的读取方法&#39;)
    def write(self):
        print(&#39;文本数据的读取方法&#39;)
class Sata(Interface): #磁盘,具体实现read和write
    def read(self):
        print(&#39;硬盘数据的读取方法&#39;)
    def write(self):
        print(&#39;硬盘数据的读取方法&#39;)
class Process(Interface):
    def read(self):
        print(&#39;进程数据的读取方法&#39;)
    def write(self):
        print(&#39;进程数据的读取方法&#39;)
登入後複製
###上面的程式碼只是看起來像接口,其實並沒有起到接口的作用,子類別完全可以不用去實現接口,這就用到了抽象類別。 #########6、抽象類別#########子類別必須繼承抽象類別的方法,不然報錯。 #########什麼是抽象類別? #########與java一樣,python也有抽象類別的概念但是同樣需要藉助模組實現,抽象類別是一個特殊的類,它的特殊之處在於只能被繼承,不能被實例化# ########為什麼要有抽象類別? #########如果說類別是從一堆物件中抽取相同的內容而來的,那麼抽象類別就是從一堆類別中抽取相同的內容而來的,內容包括資料屬性和函數屬性。 ###

比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。你永远无法吃到一个叫做水果的东西。

从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。

抽象类与接口

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计。

例1

import abc
#抽象类:本质还是类,与普通类额外的特点的是:加了装饰器的函数,子类必须实现他们
class Animal(metaclass=abc.ABCMeta):   # 抽象类是用来被子类继承的,不是用来实例化的
    tag=&#39;123123123123123&#39;
    @abc.abstractmethod   # 如果子类没有我这个函数,主动抛出异常
    def run(self):
        pass
    @abc.abstractmethod
    def speak(self):
        pass
class People(Animal):
    def run(self):   # 子类必须有抽象类里的装饰器下面的函数
        pass
    def speak(self):
        pass
peo1=People()   # 实例化出来一个人
print(peo1.tag)
登入後複製

例2

#_*_coding:utf-8_*_
__author__ = &#39;Linhaifeng&#39;
#一切皆文件
import abc #利用abc模块实现抽象类
class All_file(metaclass=abc.ABCMeta):
    all_type=&#39;file&#39;
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        &#39;子类必须定义读功能&#39;
        pass
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        &#39;子类必须定义写功能&#39;
        pass
# class Txt(All_file):
#     pass
#
# t1=Txt() #报错,子类没有定义抽象方法
class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;文本数据的读取方法&#39;)
    def write(self):
        print(&#39;文本数据的读取方法&#39;)
class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;硬盘数据的读取方法&#39;)
    def write(self):
        print(&#39;硬盘数据的读取方法&#39;)
class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(&#39;进程数据的读取方法&#39;)
    def write(self):
        print(&#39;进程数据的读取方法&#39;)
wenbenwenjian=Txt()
yingpanwenjian=Sata()
jinchengwenjian=Process()
#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()
print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)
登入後複製

以上是一文了解什麼是Python物件導向中的繼承的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles