99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁大數(shù)據(jù)時代類的繼承和多態(tài),簡易的Python面向?qū)ο蠼坛?/a>
類的繼承和多態(tài),簡易的Python面向?qū)ο蠼坛?/h5>
2021-03-12
收藏

來源:麥叔編程

作者:麥叔

面向?qū)ο笫撬懈呒壵Z言(Python,Java,C++等)的基石,是重中之重。

這個文章系列的目的是通過簡單易懂的例子,深入淺出,讓Python學習者牢固地掌握Python面向?qū)ο蟮母拍詈头椒ā?/span>

本系列包括:

  • 面向?qū)ο?1) - 屬性,構(gòu)造方法,self關(guān)鍵詞。
  • 面向?qū)ο?2) - 實例方法 (本文)
  • 面向?qū)ο?3) - 類屬性和類方法
  • 面向?qū)ο?4) - 繼承和多態(tài),以及一個綜合小游戲案例
類的繼承和多態(tài),簡易的Python面向?qū)ο蠼坛? class=

類的繼承,父類,子類

看這張圖:

類的繼承和多態(tài),簡易的Python面向?qū)ο蠼坛? class=
  1. 上面有一條小狗,代表了普通的狗。
  2. 下面有警犬,牧羊犬和寵物犬,他們都是狗。
  3. 但他們又有獨特的特點,具有額外的屬性或者技能。
  4. 警犬有偵探功能,所以有detect()方法,有額外的屬性ability,表示它的偵探能力等級。
  5. 牧羊犬有保護養(yǎng)的功能,所以有protect()方法,有額外的num_of_sheeps表示它可以保護幾只羊。
  6. 寵物犬有唱歌的功能,所以有sing()方法,有額外的屬性price表示價格。

動物界具有天然的繼承關(guān)系,人類也是,我們一代代繼承下來。繼承了前輩們的屬性和能力,又發(fā)展了自己獨特的屬性和能力。

在圖中的例子,我們?nèi)绾卧诔绦蛑斜硎酒胀ǖ墓?,牧羊犬,警犬等呢?

我們可以把detect(), protect()等函數(shù)和屬性直接加在Dog里面,但這并不合理,因為并不是所有的狗可以偵查,并不是所有的狗都可以保護養(yǎng)。

正確的做法是創(chuàng)建新的類,這些新的類繼承Dog類:

  • SheepDog 表示牧羊犬
  • PoliceDog 表示警犬
  • PetDog 表示寵物犬

在這里Dog被稱為父類,SheepDog等被稱為子類。

子類會自動擁有父類的屬性和方法,自己也可以添加自己的獨特屬性和方法。

子類的定義

現(xiàn)在來定義SheepDog。先看看我們原來的Dog類:

#類是一個模板 class Dog:     num_of_dogs = 0  # 類屬性     police_height = 60     #構(gòu)造方法 - 添加實例屬性,做其他的初始化工作     def __init__(self, name, height, power):
        self.name = name
        self.height = height
        self.power = power
        self.blood = 10         print(f"{self.name}出生了,汪汪!")
        Dog.num_of_dogs += 1     
    #狗叫     def bark(self):
        print(f'我是{self.name},汪汪汪!')

定義子類SheepDog

class SheepDog(Dog):     '''牧羊犬,包括名字,高度,攻擊力和能看護的養(yǎng)的個數(shù)'''     def __init__(self, name, height, power, num_of_sheeps):         super().__init__(name, height, power)
        self.num_of_sheeps = num_of_sheeps

仔細閱讀上面的代碼,觀察它的特點:

聲明繼承關(guān)系

SheepDog(Dog) 這種寫法:括號中的Dog表示Dog是SheepDog的父類。

我們定義Dog的時候沒有括號,表示它沒有父類(實際上它默認繼承了Object類)。

構(gòu)造函數(shù)和super()方法

  1. 子類也有構(gòu)造函數(shù)init方法,傳入各項必要的屬性。
  2. 構(gòu)造函數(shù)的第一行調(diào)用父類的構(gòu)造函數(shù),因為牧羊犬首先也是一個Dog,所以要先構(gòu)造一個Dog出來。
  3. 其中super()代表父類。我們用self表示自己,用super()表示父類。注意self是一個關(guān)鍵詞,是沒有括號的,super()是一個函數(shù),是有括號的。值得注意的是,使用self可以訪問父類的屬性和方法,因為父類的就是自己的。在構(gòu)造函數(shù)中我們使用super()來調(diào)用父類的構(gòu)造函數(shù)是因為子類和父類都有__init__方法,如果不適用super()就會調(diào)用自己的__init__方法,這種情況下需要用super)()來明確指定要訪問父類的方法。
  4. 第二行添加了牧羊犬的獨特屬性num_of_sheeps。這樣牧羊犬有4個屬性,其中3個屬性是繼承自父類的,一個是自己獨有的。

使用子類

子類的使用和父類是一樣的:

  1. 調(diào)用構(gòu)造函數(shù)創(chuàng)建實例。
  2. 通過變量名訪問屬性。
  3. 通過變量名調(diào)用方法。注意bark()是父類的函數(shù),子類可以直接使用。
sd1 = SheepDog('大黃'678810)
print(f'名字:{sd1.name}')
print(f'血量:{sd1.blood}')
print(f'高度:{sd1.power}')
sd1.bark()

給子類添加新的方法

我們給SheepDog添加它的獨特方法protect():

class SheepDog(Dog):     '''牧羊犬,包括名字,高度,攻擊力和能看護的養(yǎng)的個數(shù)'''     def __init__(self, name, height, power, num_of_sheeps):         super().__init__(name, height, power)
        self.num_of_sheeps = num_of_sheeps

    def protect(self):         print('我開始保護小羊啦!')

調(diào)用一下試試看:

sd1 = SheepDog('大黃', 67, 88, 10) sd1.protect()

覆蓋父類的方法

因為繼承的關(guān)系,SheepDog直接就有bark()方法,這是從父類繼承過來的。

假設(shè)牧羊犬的叫聲和普通叫聲是不一樣的,我們在子類中覆蓋父類中的方法:

class SheepDog(Dog):     '''牧羊犬,包括名字,高度,攻擊力和能看護的養(yǎng)的個數(shù)'''     def __init__(self, name, height, power, num_of_sheeps):         super().__init__(name, height, power)
        self.num_of_sheeps = num_of_sheeps

    def protect(self):         print('我開始保護小羊啦!')

    def bark(self):         print('我是牧羊犬,我驕傲!')

這時候再調(diào)用bark()方法就會使用子類中定義的方法:

sd1 = SheepDog('大黃', 67, 88, 10) sd1.bark()

打印的結(jié)果是:

我是牧羊犬,我驕傲!

集成和覆蓋的用處舉例

類的繼承和對父類方法的覆蓋在代碼設(shè)計中很有用。假設(shè)有個程序的界面是這樣的:

類的繼承和多態(tài),簡易的Python面向?qū)ο蠼坛? class=

按鈕就是一個類,比如叫做Button。

為了實現(xiàn)不同的皮膚,我們可以寫一個類繼承Button類,假設(shè)就叫做MyButton吧,子類自動擁有了父類的屬性和函數(shù),但是我們可以覆蓋某些函數(shù),讓他擁有不同的皮膚,甚至不同的行為。

Dog版本的吃雞游戲

面向?qū)ο蟮暮诵闹R到這里就更新完了,最后奉上Dog版本的吃雞游戲。這個游戲包含兩個類:

  • 其中dog.py定義了幾個狗類
  • game.py中創(chuàng)建100條Dog并讓他們互相攻擊,直到最后只有一只為止。

dog.py

#2種狗具有不同的攻擊力和防御能力。攻擊強的防御弱;反之亦然; import random class Dog:  dogs = [] #保存所有活著的Dog  def __init__(self, name):
  self.name = name 
  self.blood = 100   self.attack_power = 5   self.defense_power = 3  #攻擊!  def attack(self, dog2):
  print(f'{self.name}攻擊{dog2.name},攻擊力:{self.attack_power},防御力:{dog2.defense_power}')
  point = self.attack_power - dog2.defense_power
  if(dog2.blood > point):
   dog2.blood -= point
   print(f'{dog2.name}受到攻擊,奮力自救,血量減少為{dog2.blood}')
  else:    dog2.blood = 0    print(f'{dog2.name}受到攻擊,失血過多,死亡!')
   Dog.dogs.remove(dog2) 
 
 #判定狗的類型  def dog_type(self):
  if(isinstance(self, SheepDog)):
   return '牧羊犬'   elif(isinstance(self, PoliceDog)):
   return '警犬'   else:    return '普通犬' #牧羊犬 class SheepDog(Dog):  def __init__(self, name):
  super().__init__(name)
  self.attack_power = random.randint(510)
  self.defense_power = random.randint(3,5) 
  print('牧羊犬{self.name}問世!')
  self.dogs.append(self) #警犬 class PoliceDog(Dog):  def __init__(self, name):
  super().__init__(name)
  self.attack_power = random.randint(813)
  self.defense_power = random.randint(1,3) 
  print('?♀?警犬{self.name}問世!')
  self.dogs.append(self)

game.py

#1. 首先創(chuàng)建100個Dog, 50個SheepDog, 50個PoliceDog #2. 每一輪游戲,隨機選出2個Dog #3. dog1先攻擊dog2,然后dog2攻擊dog1 #3. 任何一方血量變?yōu)?就表明死亡!死亡的Dog退出游戲。 #4. 最后只有一個Dog了,游戲結(jié)束,勝利者可以吃雞。 from dog import * import random #產(chǎn)生隨機數(shù)字 import time #時間模塊 #1.創(chuàng)建100條狗 for i in range(100):
 if(i%2==0):
  SheepDog(i+1#創(chuàng)建1個牧羊犬  else:
  PoliceDog(i+1#創(chuàng)建1個警犬 #2. 開始游戲循環(huán) while(True):
 #判斷是否只有1個Dog  if(len(Dog.dogs) == 1):
  winner = Dog.dogs[0]
  print('')
  print('大吉大利,今晚吃雞!')
  print(f'贏家是:{winner.dog_type()} {winner.name}')
  print('')
  break  dog1, dog2 = random.sample(Dog.dogs, 2)
 dog1.attack(dog2)
 dog2.attack(dog1)
 time.sleep(0.02)

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }