1. 程式人生 > 其它 >Python第7課:面向物件三特性示例

Python第7課:面向物件三特性示例

技術標籤:pythonpython面向物件程式設計封裝多型

基礎知識:

  • 面向物件三特性
    • 封裝
    • 繼承
    • 多型
# 建立類
class demo:
	# 建立類中函式方法
    def demoFun(self):   # self:特殊引數,必填
    	# 方法內容
    	print("方法內容") 	
# 建立物件
odj = demo()   

封裝

class demo1:
    def demo1Fun(self):
        print("我是方法")
obj = demo1()  # 建立物件
obj.demo1Fun(
) # 通過物件呼叫方法
我是方法
class demo2:
    # 構造方法,類例項化時初始化資料
    def __init__(self,name,age):
        self.name=name
        self.age=age
    # show方法
    def show(self):
        print('當前物件的姓名為:'+self.name+',今年'+str(self.age)+'歲了!')
        
# 帶參構造方法建立物件
obj1 = demo2("李明特",22)
obj2 = demo2("楊同學"
,18) obj1.show() obj2.show()
當前物件的姓名為:李明特,今年22歲了!
當前物件的姓名為:楊同學,今年18歲了!

self

  • 是個形式引數
  • 當執行obj1 = demo2(‘李明特’,22)時,self等於obj1

通過self呼叫被封裝的內容

class calculator:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def jia(self):
        print(self.a + self.b)
    def jian(self):
        print
(self.a - self.b) def cheng(self): print(self.a * self.b) def chu(self): print(self.a / self.b) cal = calculator(2,4) cal.jia() cal.jian() cal.cheng() cal.chu()
6
-2
8
0.5

練習1

  • 遊戲程式
    • 建立三個人物:
      • 鎧甲勇士,男,18,戰鬥力1000
      • 迪迦奧特曼,男,20,戰鬥力2000
      • 喜羊羊,男,10,戰鬥力20
    • 遊戲場景
      • 戰鬥
      • 讀書
      • 看報
# 練習1
class person:
    def __init__(self,name,sex,age,power):
        self.name = name
        self.sex = sex
        self.age = age
        self.power = power
    def fight(self):
        print("{},{}歲。在打架".format(self.name,self.age))
    def book(self):
        print("{},{}歲。在讀書".format(self.name,self.age))
    def newspaper(self):
        print("{},{}歲。在讀報,".format(self.name,self.age))
kaijia = person("鎧甲勇士","男",18,1000)
dijia = person("迪迦奧特曼","男",20,2000)
xiyang = person("喜羊羊","男",10,20)

kaijia.fight()
dijia.book()
xiyang.newspaper()
鎧甲勇士,18歲。在打架
迪迦奧特曼,20歲。在讀書
喜羊羊,10歲。在讀報,

繼承

  • 將多個類的共同方法提取到父類中,子類僅需繼承父類即可呼叫父類方法
  • 除了子類和父類,還有叫派生類和基類的,稱呼不同而已

多繼承

  • 繼承多個類時,尋找方法的方式有兩種
  • 深度優先:
    • 說白了深度優先遍歷就是一種不撞南牆不會頭的演算法,他會把一條路走完之後再回溯到有分叉的節點繼續遍歷
      • 當類是經典類時
                class C1:
                    pass
                class C2(C1):
                    pass
                # C1和C2是經典類
  • 廣度優先:
    • 廣度優先搜尋是按層來處理頂點,距離開始點最近的那些頂點首先被訪問,而最遠的那些頂點則最後被訪問
      • 當類是新式類時
                class N1(object):
                    pass
                class N2(N1):
                    pass
                # N1和N2是新式類 
  • 在上述查詢過程中一旦找到則尋找過程立即中斷,不會繼續查找了

object

  • python3中預設載入了object(即便你沒有寫上object)
  • 擁有更多的可操作物件,是類的高階特性,對於著手寫框架或者寫大型專案的選手這些特性才比較有用。
# py3中預設載入object
class test:
    name = "不帶object類"
a = test
# 內建函式dir()能夠顯示沒模組中定義了哪些名字,返回一個排序好的字串列表
# 包括變數名、函式名、模組名
print(dir(a))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']
# 練習2
# 定義一個動物類
class animal:
    def jiao(self):
        print("{}{},叫".format(self.breed,self.name))
    def eat(self):
        print("{}{},吃".format(self.breed,self.name))
        
# 小貓咪例項
class cat(animal):      # 括號內寫繼承的父類名稱
    def __init__(self,name):
        self.name = name
        self.breed = '小貓'
    def maojiao(self):
        print("小貓喵喵叫")
        
# 小狗例項
class dog(animal):      # 括號中寫繼承的父類名稱
    def __init__(self,name):
        self.name = name
        self.breed = '小狗'
    def goujiao(self):
        print("小狗汪汪叫")

# 例項化物件
cat1 = cat("湯姆")
dog1 = dog("山姆")

cat1.eat() # 呼叫父類方法
dog1.jiao() # 呼叫父類方法
print("-------------")
cat1.maojiao() # 呼叫子類方法
dog1.goujiao() # 呼叫子類方法

小貓湯姆,吃
小狗山姆,叫
-------------
小貓喵喵叫
小狗汪汪叫

多型

  • 多型是指不同的子類在繼承父類後分別都重寫覆蓋了父類的方法,即父類同一個方法,在繼承的子類中表現出不同的形式
  • 繼承是多型的前提,函式重寫就是多型的體現形式

練習3

  • 飼養員餵養熊貓和猴子、老虎等動物
    • 定義飼養員的類和動物的類
    • 定義猴子類,熊貓類等繼承動物類
    • 在飼養員中定義類成員方法,餵養
# 練習3
# 1.定義飼養員類和動物類
class Person:
#     def feedPanda(self,panda):
#         print("飼養員用 " + panda.food + " 餵養 " + panda.name)
#     def feedMonkey(self,monkey):
#         print("飼養員用 " + monkey.food + " 餵養 " + monkey.name)
#     def feedTiger(self,tiger):
#         print("飼養員用 " + tiger.food + " 餵養 " + tiger.name)
    def feedAnimal(self,ani):   
        # 隨便寫個形參代表一個具體動物,在下面將動物例項傳進來
        print("飼養員用 " + ani.food + " 餵養 " + ani.name)
class Animal:
    def __init__(self,name,food):
        self.name = name
        self.food = food
    def eat(self):
        print(self.name + " 在吃 " + self.food)

# 2.定義猴子、熊貓、老虎類繼承動物類
class Monkey(Animal):
    def __init__(self,name,food):
        super().__init__(name,food)
class Panda(Animal):
    def __init__(self,name,food):
        super().__init__(name,food)
class Tiger(Animal):
    def __init__(self,name,food):
        super().__init__(name,food)

panda = Panda("阿寶","包子")
monkey = Monkey("吉吉國王","香蕉")
tiger = Tiger("悍嬌虎","麵條")
# 建立一個飼養員例項
P = Person()
P.feedAnimal(panda)
P.feedAnimal(monkey)
P.feedAnimal(tiger)
# P.feedMonkey(monkey)
# P.feedPanda(panda)
# P.feedTiger(tiger)
飼養員用 包子 餵養 阿寶
飼養員用 香蕉 餵養 吉吉國王
飼養員用 麵條 餵養 悍嬌虎

super()的使用

子類繼承父類,但不重寫構造方法__init__(初始化),那麼子類會自動繼承父類屬性和方法
class fu:
    def __init__(self):
        self.name = "李同學"
        self.age = "20"
    def hello(self):
        print(self.name+"對你說他今年"+self.age+"歲了,並向你問好!")
        print("已繼承父類方法")
class zi(fu):
    pass
F = fu()
Z = zi()
print("子類繼承父類的屬性:"+Z.name+"今年"+Z.age+"歲")
Z.hello()
子類繼承父類的屬性:李同學今年20歲
李同學對你說他今年20歲了,並向你問好!
已繼承父類方法
子類繼承父類,重寫構造方法__init__(初始化),但不使用super初始化父類構造方法,那麼子類不會自動繼承父類的屬性,會繼承方法
class fu:
    def __init__(self):
        self.name = "李同學"
        self.age = "20"
    def hello(self):
        # print(self.name+"對你說他今年"+self.age+"歲了,並向你問好!") 
        # 子類在不適用super的情況下繼承的父類方法不能有子類沒有的屬性,這裡子類沒有name和age
        # 但是子類可以正常繼承父類方法
        print("已繼承父類方法")
class zi(fu):
    def __init__(self):
        self.lover = "楊同學"
F = fu()
Z = zi()
print("父類屬性:"+F.name+"今年"+F.age+"歲")
# print("子類屬性:"+Z.name+"今年"+Z.age+"歲")   沒有繼承父類的屬性
# 這句話會報錯:AttributeError: 'zi' object has no attribute 'name'
# 因為子類在沒用super初始化父類構造方法時不會繼承父類屬性,但是會繼承方法
print("子類屬性:"+Z.lover)
Z.hello()   # 正常繼承了父類方法
父類屬性:李同學今年20歲
子類屬性:楊同學
已繼承父類方法
子類繼承父類,重寫建構函式__init__(初始化),且使用super初始化父類建構函式,那麼子類會自動繼承父類的屬性和方法
class fu:
    def __init__(self):
        self.name = "李同學"
        self.age = "20"
    def hello(self):
        print(self.name+"對你說他今年"+self.age+"歲了,並向你問好!")
        print("已繼承父類方法")
class zi(fu):
    def __init__(self):
        super().__init__()
        self.lover = "楊同學"
F = fu()
Z = zi()
print("父類屬性:"+F.name+"今年"+F.age+"歲了")
print("子類屬性:"+Z.name+"今年"+Z.age+"歲了,女朋友是"+Z.lover)    # 這裡子類繼承了父類的屬性值
Z.hello()   # 繼承了父類方法
父類屬性:李同學今年20歲了
子類屬性:李同學今年20歲了,女朋友是楊同學
李同學對你說他今年20歲了,並向你問好!
已繼承父類方法