Python-初識面向對象

什麼是面向對象?

面向對象指的是一門編程的思想,python中一切皆對象。編程

面向過程 VS 面向對象

  • 面向過程編程:

核心是 「過程」 二字,過程指的是作事情的步驟,即先作什麼再作什麼,函數

基於該編程思想寫程序,就比如一個工廠流水線,一種機械式的思惟方式code

優勢:邏輯清晰,複雜的問題簡單化對象

缺點:可擴展性差get

  • 面向對象編程:

核心是 「對象」 二字,對象指的是特徵和技能的結合體it

基於該編程思想寫程序,就比如在創造世界,一種上帝式的思惟方式面向對象編程

優勢:可擴展性高class

缺點:編寫程序複雜程度高擴展

那麼咱們在編程的時候優先使用 面向過程思想 呢?仍是面向對象思想呢?

一般是二者結合在一塊兒使用

類與對象定義

對象:特徵和技能的結合體

類:一系列對象相同的特徵和技能的結合體

在現實生活中 先有一個一個對象,而後再有人們對類的概念,
在程序中 必須定義好類,而後調用類來創造對象

定義類:

​ class 類名
​ 相同的特徵
​ 相同的技能

class Stut: # 類名,遵循駝峯體命名規範,首字母大寫
    # 特徵
    school = "oldboy"
    # 技能
    def learn(self):
        print("learning...")

定義類發生的兩件事情

  1. 生成一個空的名稱空間
  2. 把類內部全部名字,扔進類的名稱空間中
  • 注意:類在定義階段產生好了名稱空間,執行py文件時候會執行類內部的代碼

建立對象

語法:類名 + () 調用產生對象

-------類調用-------
# 在咱們定義好類以後,咱們能夠調用類的屬性和方法
print(Stut.__dict__.get("school"))      # 類名.__dict__獲取類內部所有屬性
Stut.learn(123)     # 使用Stut的learn方法,此時由類來調用類內部的函數,該函數只是一個普通的函數,類內部learn函數有一個形參,那麼在調用的時候也必須傳一個參數才能調用


-------對象調用-------
s1 = Stut() # s1 -》 <__main__.Stut object at 0x0000000009FA9DD8>
#在咱們實例化類 建立出來一個s1對象以後,咱們可使用對象.屬性來調用
print(s1.school)
s1.learn()      # 由對象來調用類內部的方法,self即對象自己,做爲第一個參數傳入。

建立對象(即調用類) 發生的三件事情

  1. 生成一個空的對象空間,
  2. 會自動觸發類內部的 __init__函數
  3. 會把建立的對象自己以及調用類傳入的參數一併傳入給 init 函數
class OldboyStudend:
    """學生類"""
    # 給不一樣對象添加不一樣特徵的方式二:
    def __init__(self,name,age,sex):
        # self 就是建立出來的對象自己,對象.屬性 能夠獲取不一樣對象的屬性
        self.name = name
        self.age = age
        self.sex = sex
        print("調用類就運行__init__函數",name,age,sex)

    school = "oldboy"

    def learn(self):
        print("正在learn...")

    def chooice_course(self):
        print("正在chooice_course...")

# print(OldboyStudend.__dict__.get("school"))


s1 = OldboyStudend("qinyj",21,"男")    # 建立出一個 名 s1的對象
s2 = OldboyStudend("jack",22,"男")    # 建立出一個 名 s2的對象
print(s1.school)        # 調用類的特徵
print(s2.school)        # 調用類的特徵


'''
問題:不一樣的對象特徵技能同樣,如何能不同
解決:兩種方式:
    - 在類內部定義 __init__ 函數
    - 建立出對象後單獨添加屬性
'''

# 給不一樣對象添加不一樣特徵的方式一:
s1.name = "qinyj"
s1.age = "21"
s1.sex = "female"

s2.name = "jack"
s2.age = "22"
s2.sex = "female"
print(s1.name,s1.age,s1.sex)
print(s2.name,s2.age,s2.sex)

對象與類的查找順序

對象中屬性的查找順序:

  1. 對象.屬性 若對象自己有,則優先查找對象本身的
  2. 若對象自己沒有,則去類裏面找
  3. 若類沒有,則報錯
class OldboyStend:
    SCHOOL = "oldboy"
    NAME = "DDDDDDDD"

    def __init__(self,name,age,sex,school):
        self.name = name
        self.age = age
        self.sex = sex
        self.SCHOOL = school

s1 = OldboyStend("qinyj",22,"男","oldgirl")
print(s1.SCHOOL)
# oldgirl

print(s1.NAME)
# DDDDDDDD

對象綁定方法

類內部的函數主要是給對象用的

  1. 類來調用類內部的函數,這時候這個函數就是一個普通的函數,這個函數有一個形參,調用的時候必須傳入幾個參數
  2. 對象來調用類內部的函數 稱之爲對象的綁定方法,不一樣的對象調用該綁定方法,則會將不一樣的對象傳入該綁定方法中
  3. 對象的綁定方法 是由對象來調用的,特殊之處就是把對象當作第一個參數傳入該方法中
class OldboyStend:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def learn(self):
        print(f"{self.name} 正在learn...")

s1 = OldboyStend("qinyj",22,"男")
s1.learn()
# qinyj 正在learn...

print(s1.learn)     # bound method 稱之爲對象的綁定方法   再也不是一個普通的函數了
# <bound method OldboyStend.learn of <__main__.OldboyStend object at 0x000000000296C400>>

實戰-人狗大做戰

'''
需求:
    人 對象
    狗 對象
    人狗互咬,若是一方生命值爲0,則該程序就結束

定義兩個類:
    人類
    狗類
'''

class People:
    def __init__(self,name,damage,life):
        # 對象特有的特徵
        self.name = name
        self.damage = damage
        self.life = life
    # 人咬狗 技能
    def bite(self,dog):
        if dog.life <= 0:
            return True
        if self.life == 0:
            print(f"{self.name} 死了,{dog.name} 贏了")
            return
        dog.life -= self.damage
        print(f'''
        人:[{self.name}] 開始咬狗:[{dog.name}]
        狗掉血:[{self.damage}]
        狗剩餘血量:[{dog.life}]
        ''')

class Dog:
    def __init__(self,name,damage,life):
        # 對象特有的特徵
        self.name = name
        self.damage = damage
        self.life = life

    # 狗咬人 技能
    def bite(self, people):
        if people.life <= 0:
            return True
        if self.life == 0:
            print(f"{self.name} 死了,{people.name} 贏了")
            return
        people.life -= self.damage
        print(f'''
        狗:[{self.name}] 開始咬人:[{people.name}]
        人掉血:[{self.damage}]
        人剩餘血量:[{people.life}]
        ''')

people = People("qinyj",200,1000)
dog = Dog("哈士奇",500,400)
while True:
    flg1 = people.bite(dog)
    if flg1:
        break
    flg2 = dog.bite(people)
    if flg2:
        break

終端打印結果:

人:[qinyj] 開始咬狗:[哈士奇]
        狗掉血:[200]
        狗剩餘血量:[200]
        

        狗:[哈士奇] 開始咬人:[qinyj]
        人掉血:[500]
        人剩餘血量:[500]
        

        人:[qinyj] 開始咬狗:[哈士奇]
        狗掉血:[200]
        狗剩餘血量:[0]
        
哈士奇 死了,qinyj 贏了

小結

面向過程編程:
        核心是「過程」二字,過程指的是作事情的步驟,即先作什麼再作什麼
        基於該編程思想編寫程序,就比如一條工廠流水線,一種機械式的思惟方式。
            優勢:邏輯清晰,複雜的問題流程化,進而簡單化。
            缺點:可擴展性差。
    面向對象編程:
        核心是「對象」二字,對象指的是特徵與技能的結合體。
        基於該編程思想編寫程序,就比如在創造世界,一種上帝式的思惟方式。
            優勢:可擴展性高。
            缺點:編寫程序的複雜程度要遠高於面向過程編程思想。

    在定義類發生的事情:
        1.類在定義時,會產生一個空的名稱空間。
        2.會把類內部全部名字,扔進類的名稱空間中。
        注意: 類在定義階段就已經產生好了名稱空間,執行python文件時會執行類內部的代碼。


    調用類發生的事情(******):
        1.首先會產生一個空的對象,就是產生「對象的名稱空間」。
        2.會自動觸發__init__。
        3.會把對象自己以及括號內的參數一併傳給__init__函數。
        總結: 調用類會產生一個對象,調用類的過程叫作類的實例化,產生的對象稱之爲類的一個實例.


    __init__: 會在調用類時,自動觸發該函數。

    對象綁定方法特殊之處
        1.類調用類內部的函數,只是調用普通函數.
        2.對象的綁定方法特殊之處(*******):
            - 由對象來調用的,會把對象看成第一個參數傳入該方法中
            - 由不一樣的對象來調用,就會把不一樣的對象傳給不一樣的綁定方法.
相關文章
相關標籤/搜索