【17】有關python面向對象編程的提升【多繼承、多態、類屬性、動態添加與限制添加屬性與方法、@property】

1、多繼承

案例1:小孩繼承自爸爸,媽媽。在程序入口模塊再建立實例調用執行函數

#father模塊
class Father(object):
    def __init__(self,money):
        self.money = money

    def play(self):
        print("play")
    def eat(self):
        print("eat")


#mother模塊
class Mother(object):
    def __init__(self,faceValue):
        self.faceValue = faceValue

    def watchTV(self):
        print("watch TV")
    def drink(self):
        print("drink!")

#child模塊
from father import Father
from mother import Mother

# 小孩繼承自父親,母親
class Child(Father,Mother):
    def __init__(self,money,faceValue):
        Father.__init__(self,money)
        Mother.__init__(self,faceValue)

#調用,程序啓動模塊
def main():
    child = Child(200,1000)
    print(child.money,child.faceValue)
    child.eat()
    child.play()
    child.watchTV()
    child.drink()


if __name__ == '__main__':
    main()

'''
輸出:
200 1000
eat
play
watch TV
drink!

'''# 注意:當兩個父類的方法是相同的名字的話,默認調用寫在多繼承前邊的那個類的方法。

2、多態

案例:貓和老鼠都是繼承自動物類,動物類有基本的名字屬性和吃的行爲,再定義一我的類,採用多態的方式來喂每個動物。spa

 

# 1 先定義一個animal類,供 任意一個新加入的動物繼承
class Animal(object):
    def __init__(self,name):
        self.name = name

    def eat(self):
        print(self.name+"")

# 2 建立一個貓類,繼承自父類animal類 from animal import Animal # 讓Cat繼承自animal父類 class Cat(Animal): def __init__(self,name): super(Cat,self).__init__(name) #單繼承的寫法規範
# 3 寫一個老鼠類,繼承父類 from animal import Animal class Mouse(Animal): def __init__(self, name): super(Mouse, self).__init__(name)

# 4 寫一我的類,其中帶有餵養任何動物的方法 from cat import Cat from mouse import Mouse class Person(object): ''' # 多種動物的話就太麻煩了 def feedCat(self,cat): print("投放食物") cat.eat() def feedMouse(self,mouse): print("給你食物") mouse.eat() ''' #用下述多態思想 --- 新的方法 def feedAnimal(self,ani): print("給你食物") ani.eat()

# 5 程序執行入口文件 from cat import Cat from mouse import Mouse from person import Person tom = Cat("Tom") jerry = Mouse("jerry") # 定義一我的類,讓他能夠喂貓,老鼠 per = Person() # 多態的喂的方法 per.feedAnimal(tom) per.feedAnimal(jerry)

'''
輸出:

給你食物
Tom吃
給你食物
jerry吃code

'''

3、類屬性與對象屬性

# 類屬性: 用類名來調用的屬性
# 對象屬性:對象調用的屬性 是__init__()的屬性

class Person(object):
    # 這裏的屬性是類屬性,用類名來調用
    name = "jiajia"
    # 下邊的是對象屬性
    def __init__(self, name):
        self.name = name

print(Person.name)
#輸出:jiajia 打印的是類屬性的信息

p=Person("LiHua")
print(p.name)
# 輸出 LiHua 打印的是對象屬性

'''
總結:
0 類屬性是類名來調用的,對象屬性是對象調用的
1 類屬性的優先級是高於對象屬性
2 用對象的方式訪問對象屬性,是打印出的是類屬性信息
如:del p.name
    print(p.name)
此時就會打印出同名的類屬性。
'''

4、動態添加屬性和方法與限制動態添加屬性與方法

# 動態的添加屬性和方法

# 建立一個空的類
class Person(object):
    # 在定義類的時候,添加一個__slots__屬性,來限制動態添加的屬性信息
    __slots__ = ('name','age','speak')



per = Person()
#1 動態的添加屬性
per.name = '佳佳'

#2 動態的添加方法
from types import MethodType
def say(self):
    print("我是中國人!")

per.speak = MethodType(say,per)
#調用
per.speak()

# 此處出錯是由於此屬性是沒法動態的添加進去的,上邊的slots方法裏面限制的名字沒有這個的。
per.facevalue = 15   


# 思考:若是想要限制實例的屬性怎麼辦?如只須要添加 name age height
# 解決方案
# 在定義類的時候,添加一個__slots__屬性,來限制動態添加的屬性信息

5、@property

這個裝飾器主要解決的是如何把私有的屬性按照正常的 方法來訪問(不寫set get方法)對象

# 若是想把__name 這種的能夠直接用per.__name訪問的話,不用函數來解決就須要用property解決啦blog

# 若是想把__name 這種的能夠直接用per.__name訪問的話,不用函數來解決就須要用property解決啦

class Person(object):
    def __init__(self,age,name):
        #屬性是直接外部暴露的
        self.age = age
        #限制訪問的方法解決,可是又須要寫set和get方法才能夠訪問
        self.__name = name
    '''
    def setName(self,name):
        self.__name=name
    def getName(self):
        return self.__name
    '''
    # 棄用上述的方法,用下邊的裝飾器的方法,訪問就能夠直接用對象點 對應的方法來訪問啦、
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,name):
        if name =='':
            print("不能夠輸入爲空!")
        else:
            self.__name= name

per = Person(24,'張老師')
# 由於上邊用了property 因此對於私有的屬性下邊依舊能夠用對象名+點+屬性的方式來訪問到。
per.name = "孫鑫"
print(per.name)
相關文章
相關標籤/搜索