python入門基礎(14)--類的屬性、成員方法、靜態方法以及繼承、重載

来源:https://www.cnblogs.com/codingchen/archive/2023/09/20/17708314.html
-Advertisement-
Play Games

上一篇提到過類的屬性,但沒有詳細介紹,本篇詳細介紹一下類的屬性 一 、類的屬性 方法是用來操作數據的,而屬性則是建模必不的內容,而且操作的數據,大多數是屬性,比如游戲中的某個boss類,它的生命值就是屬性(不同級別的boss,有不同的生命值),被攻擊方法(不同的攻擊,傷害值不同),當boss被攻擊時 ...


上一篇提到過類的屬性,但沒有詳細介紹,本篇詳細介紹一下類的屬性

一 、類的屬性

  方法是用來操作數據的,而屬性則是建模必不的內容,而且操作的數據,大多數是屬性,比如游戲中的某個boss類,它的生命值就是屬性(不同級別的boss,有不同的生命值),被攻擊方法(不同的攻擊,傷害值不同),當boss被攻擊時,通過被攻擊方法來減少boss自身的生命值,從而改變boss類的生命值屬性。  

   python中類的屬性有兩類:實例屬性和類屬性 面向對象編程最大好處就是通過繼承來減少代碼,同時可以定製新類。類的繼承,創建的新類稱為了類,被繼承的類為父類。子類繼承父類後,子類就具有父類的屬性和方法,但不能繼承父類的私有屬性和私有方法(屬性名或方法名以兩個下畫線開頭的),子類可以通過重載來修改父類的方法,以實現與父類不同的行為表現或能力。

下麵通過一個代碼實例,進行介紹,代碼如下:

class Demo_Property:              #定義類
    class_name = "Demo_Property"  #類屬性

    def __init__ (self,x=0):  #實例屬性
        self.x = x

    def class_info(self):   #輸出信息方法
        print("類變數值:",Demo_Property.class_name)
        print("實例變數值:",self.x)
    
    def chng(self,x):    #修改實例屬性的方法
        self.x=x  #註意實例屬性的引用方式        
        
    def chng_cn(self,name):   #修改類屬性的方法
        Demo_Property.class_name = name  #註意類屬性引用方式
        
dpa = Demo_Property()   #創建一個對象dpa,也就是實例化類
dpb = Demo_Property()   #創建一個對象dpb,即實例化類

print('初始化兩個實例')
dpa.class_info()
dpb.class_info()

print('修改實例變數')
print('修改dpa 實例變數\n')
dpa.chng(3)
dpa.class_info()
dpb.class_info()

print('修改dpb實例變數\n')
dpb.chng(10)
dpa.class_info()
dpb.class_info

print('修改類變數')
print('修改 dpa類變數\n')
dpa.chng_cn ('dpa')
dpa.class_info()
dpb.class_info()

print('修改dpb實例變數\n')
dpb.chng_cn ('dpb')
dpa.class_info()
dpb.class_info()

代碼說明:第一行定義Demo_property類,第二行class_name = "Demo_Property"  #定義了類的屬性class_name,接下來的兩行,定義了實例屬性x,

後面三個def 分別定義了一個輸入信息的方法class_info,一個修改實例屬性的方法chng,一個修改類屬性的方法chng_cn。再創建了兩個實例dpa和dpb。

dpa.class_info()和dpb.class_info()分別調用class_info()方法分別列印類變數值和實例變數值。後面的幾行,分別通過修改變數,來實現實例變數、類變數的變化。運行結果如下:

二、類成員方法與靜態方法

和屬性一樣,類的方法也有不同類型,主要有實例方法、類方法、靜態方法。上述所有類中的方法都是實例方法,隱含調用參數是類的實例,類方法隱含調用的是類,靜態方法沒有隱含參數。

類方法和靜態方法的定義方式與實例方法不同,調用方式也不相同。

靜態方法定義的時候用裝飾器@staticmethod進行修飾,沒有預設參數

類方法定義時應用裝飾器@classmethod進行修飾,必須有預設參數“cls”,兩者調用方式可以直接由類名進行,既可用該類的任一個實例進行調用 ,也可以在

實例化前調用。如下例子:

class DemoMthd:
    @staticmethod   #靜態方法裝飾器
    def static_mthd():   #定義一個靜態類
        print("調用了靜態方法!")
    @classmethod    #類方法裝飾器
    def class_mthd(cls):  #類方法定義,帶預設參數cls
        print("調用了類方法!")
        
DemoMthd.static_mthd()   #未實例化類,通過類名調用靜態方法
DemoMthd.class_mthd()    #未實例化類,通過類名調用類方法

dm = DemoMthd ()   #創建對象,實例化
dm.static_mthd()   #通過實例調用靜態方法 
dm.class_mthd()    #通過實例調用類方法

註意:仔細分析上面代碼中的註釋。運行結果如下:

三、類的繼承

       通過上述例子,可以看出,我們在創建dpa和dpb時(其他例子中的多個對象),只通過實例化就創建了具體相同結構的對象,這就是面向對象編程的好處:減少代碼量。

但如果dpa,dpb大部分結構相同,但又有所不同,比如游戲中的不同級別的boss,小boss,只有砍的攻擊方法,而大boss,除了砍,還有噴火、掃腿……等不同的攻擊方法(如上一篇中的,走、唱、跑方法一樣),該如何處理?這就需要用到類的繼承。類的繼承,不僅可以減少代碼量,同時還可以定製新類。

類的繼承,創建的新類稱為子類,被繼承的類為父類。子類繼承父類後,子類就具有父類的屬性和方法,但不能繼承父類的私有屬性和私有方法(屬性名或方法名以兩個下畫線開頭的),子類可以通過重載(後面會演示)來修改父類的方法,以實現與父類不同的行為表現或能力。

那我們可以思考一下,將上一篇中的cat進行更加抽象成一個新類animal,然後cat的繼承animal的屬性,於是得到以下代碼:

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 16 19:59:24 2023

@author: Administrator
"""

def coord_chng(x,y):        #定義一個全局函數,模擬坐標值變換
    return (abs(x),abs(y))  #將x,y 值求絕對值後返回

class Animal:
    def __init__ (self,lifevalue): 
        self.lifevalue=lifevalue
        
    def info(self):      #定義一個方法
         print("當前位置:(%d,%d)"% (self.x,self.y))   
    def crawl(self,x,y):
         self.x=x
         self.y=y
         print("爬行……")
         self.info()    
         
    def move(self,x,y):        #定義一個方法move()
            x,y = coord_chng(x,y)  #調用全局函數,坐標變換
            self.edit_point(x,y)   #調用類中的方法edit_point()
            self.disp_point()      #調用類中的方法disp_point()
        
    def edit_point(self,x,y):  #定義一個方法
            self.x += x
            self.y += y

    def disp_point(self):      #定義一個方法
            print("當前位置:(%d,%d)"% (self.x,self.y))     
    
class Cat(Animal):          #定義一個類Cat類,繼承類Animal
    def __init__ (self,x=0,y=0,color="white"):  #定義一個構造方法
        self.x=x
        self.y=y
        self.color=color      #新增加一個顏色
        self.disp_point()      #構造函數中調用類中的方法disp_point()
    
    def run(self,x,y):        #定義一個方法run()
            x,y = coord_chng(x,y)  #調用全局函數,坐標變換
            self.edit_point(x,y)   #調用類中的方法edit_point()
            self.disp_point()      #調用類中的方法disp_point()
     

cat_a= Cat()      #實例化Cat()類
cat_a.move(2,4)   #調用cat_a實例的方法move()
cat_a.move(-9,6)  #調用cat_a實例的方法move()
cat_a.move(12,-16)#調用cat_a實例的方法move()
cat_a.run(12,-16) #調用cat_a實例的方法run()

註意紅色註釋部分,move()這個方法是Cat類沒有的,但在Animal中有,Cat類通過繼承Animal類,獲得了Animal中move方法。

同樣,也可以將上篇中的Person類繼承Animal類的功能,併進行少量修改,全部代碼如下:

# -*- coding: utf-8 -*-
"""
Created on Sun Sep 17 19:59:24 2023

@author: Administrator
"""

def coord_chng(x,y):        #定義一個全局函數,模擬坐標值變換
    return (abs(x),abs(y))  #將x,y 值求絕對值後返回

class Animal:
    def __init__ (self,lifevalue): 
        self.lifevalue=lifevalue
        
    def info(self):      #定義一個方法
         print("當前位置:(%d,%d)"% (self.x,self.y))   
    def crawl(self,x,y):
         self.x=x
         self.y=y
         print("爬行……")
         self.info()  
def move(self,x,y): #定義一個方法move() x,y = coord_chng(x,y) #調用全局函數,坐標變換 self.edit_point(x,y) #調用類中的方法edit_point() self.disp_point() #調用類中的方法disp_point() def edit_point(self,x,y): #定義一個方法 self.x += x self.y += y def disp_point(self): #定義一個方法 print("當前位置:(%d,%d)"% (self.x,self.y)) class Cat(Animal): #定義一個類Cat類,繼承類Animal def __init__ (self,x=0,y=0,color="white"): #定義一個構造方法 self.x=x self.y=y self.color=color #新增加一個顏色 self.disp_point() #構造函數中調用類中的方法disp_point() class Person(Animal): #定義一個類Person類,繼承類Animal def __init__(self,new_name,x,y,new_age,new_hight,new_weight,edu_certification,new_job): #self.name = "Tom" self.x=x self.y=y self.name=new_name self.age=new_age self.hight=new_hight self.weight=new_weight self.edu_certif=edu_certification self.job=new_job def eat(self): # 哪一個對象調用的方法,self就是哪一個對象的引用 print("%s 愛吃魚" % self.name) def drink(self): print("%s 要喝水" % self.name) def walk(self): print("%s今天步行了10公裡"%self.name) def run(self): # 必須返回一個字元串 return "%s跑了10公裡,用時56分鐘。" % self.name def sing(self): # 必須返回一個字元串 return "%s唱了一首《我的中國心》" % self.name def working(self): # 必須返回一個字元串 return "%s工作了很久!" % self.name tom=Person("Tom",10,20,24,175,70,"bachelor","writer") #lucy=Person("Lucy") #lily=Person("Lily") print("%s的身高是%s cm\n" %(tom.name,tom.hight)) print("%s的體重是%sKG\n" %(tom.name,tom.weight)) print(tom.sing()) print(tom.run()) tom.move(2,4) tom.move(10,-12) print("------------------顯示分隔線--------------------\n") cat_a= Cat() #實例化Cat()類 cat_a.move(2,4) #調用cat_a實例的方法move() cat_a.move(12,-16)#調用cat_a實例的方法move()

代碼中紅色部分為修改。可以看出,tom繼承Animal類後,也繼承了move()方法。運行結果:

 

四、類的多重繼承

python編程中,一個類不僅可以繼承一個類,還可以繼承多個類,即多重繼承。和上述所講繼承一樣,只不過在括弧中,用“,”分隔開。可以當作思考題,自動動手,比如利用上述的person類,Cat類,創建一個怪物類,然後實例化。

五、方法的重載

當子類繼承父類時,子類如果要想修改父類的行為,則應使用方法重載來實現,
方法重載:在子類中定義一個和所繼承的父類中,同名的方法。

比如,上述代碼中animal類中有一個move()方法,如果將子類Person中的def run(self) 修改為def move(self),即move()方法被 重載了

當用子類Person創建對象(實例化)後,調用的是Person類中的move()。

同樣,如果在多重繼承中,兩個父類具有同名方法,為避免不要求的錯誤,在子類中對該方法進行重載。

 

 

翻譯

搜索

複製


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 眾所周知,在現實世界中,每一個資源都有其提供能力的最大上限,當單一資源達到最大上限後就得讓多個資源同時提供其能力來滿足使用方的需求。同理,在電腦世界中,單一資料庫資源不能滿足使用需求時,我們也會考慮使用多個資料庫同時提供服務來滿足需求。當使用了多個資料庫來提供服務時,最為關鍵的點是如何讓每一個數據 ...
  • web前端JavaScript交互 點擊事件 意義: JavaScript中的點擊事件是指當用戶在頁面上點擊某個元素時觸發的事件。這個事件可以用於執行各種操作,如改變元素的樣式、修改頁面內容等。這是Web應用程式中最常用 的交互方式之一,允許用戶與網頁進行交互,提高用戶體驗。 案例: 隨機點名器 知 ...
  • 工作中經常遇到按照指定格式的時間進行展示。可參考以下腳本邏輯滿足需求 Date.prototype.PtTimeByFormat = function (fmt){ var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 可選鏈運算符(?.),大家都很熟悉了,直接看個例子: const result = obj?.a?.b?.c?.d 很簡單例子,上面代碼?前面的屬性如果是空值(null或undefined),則result值是undefined,反 ...
  • import React, { useEffect, useState } from 'react'; hook 是react 16.8的新增特性 ,他可以讓你不在編寫class的情況下shiystate以及react的特性 Hooks的出現,首先解決了以下問題: 告別了令人疑惑的生命周期 告別類組 ...
  • 設計模式 學習推薦設計模式目錄:22種設計模式 (refactoringguru.cn) 圖說設計模式 — Graphic Design Patterns (design-patterns.readthedocs.io) UML類圖初見 什麼是統一建模語言(UML)? (visual-paradig ...
  • 一、前言 這篇博客是對軟體工程導論的個人項目進行互評,項目要求實現一個簡單的中小學數學卷子自動生成程式。我的搭檔謝先衍同學使用Python完成了項目,而我則是使用java。儘管語言不同增加了一定的閱讀成本,但是接觸到另一種新語言並體會編程者發揮語言特性獨特的心得,確實是拓展了眼界。一個項目,最終歸結 ...
  • KMP演算法是一種高效的字元串匹配演算法,它的核心思想是利用已經匹配成功的子串首碼的信息,避免重覆匹配,從而達到提高匹配效率的目的。KMP演算法的核心是構建模式串的首碼數組Next,Next數組的意義是:當模式串中的某個字元與主串中的某個字元失配時,Next數組記錄了模式串中應該回退到哪個位置,以便繼續匹... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...