python-33 面向對象之二:組合、繼承

 

1.當類之間有顯著的不一樣,而且較小的類是較大的類所須要的組件時,用組合較好python

 

'''
1.組合:在一個類中以另一個類的對象做爲數據屬性,稱爲類的組合
'''
class School:
    def __init__(self,name,add):
        self.name=name
        self.add=add

class Course:
    def __init__(self,name,price,priod,school):
        self.name=name
        self.price=price
        self.priod=priod
        self.school=school  #傳入一個類,這樣就構成了一個組合,一類中包含了另外一個類

s1=School('清華','北京')
s2=School('科大','合肥')

c1=Course('python','1w','3mon',s1) #這就是組合,大類中包含小類
c2=Course('linux','2w','4mon',s2)

print(c1.school.name)
print(s1,'\n',c1.__dict__['school'])#打印 s1內存地址,地址相同
View Code

 

 2.當類之間有許多共同的功能,提取這些共同的功能作基類,用繼承較好linux

    繼承:具備兩方面含義,一是繼承父類的特性,二是具備本身衍生的特性ide

   單繼承:從上往下繼承,先繼承祖先類,再繼承子孫類的類數據屬性和方法屬性,實例化時,先查找本身的__init__方法,沒有再往上找,直到找到爲止,工具

                   若是都沒有顯示的__init__方法,調用object類的__init__方法spa

 

class A:
    print('---A---')
    def __init__(self,name):
        self.name=name
        print('A:name=%s'%self.name)
    def eat(self):
        print('%s正在吃ing'%self.name)
class B(A):
    a=1
    print('---B---')
class C(B):
    print('---C---')
    def __init__(self,sex,age):
        self.g=super().__init__('小a')
        self.sex=sex
        self.age=age
        print('C:sex=%s  age=%s'%(sex,age))

c=C('boy',50)#先打印 B C類的數據屬性,至關於先將打印的代碼加載到C類中,再調用父類的__init__,最後是自身的__init__方法
c.eat()#小a正在吃ing
print(c.__dict__)#{'name': '小a', 'g': None, 'sex': 'boy', 'age': 50},擁有了name數據屬性
View Code

 

 

多繼承:根據mro線性順序表繼承(廣度優先查找),一樣先繼承全部父類的數據屬性,再查找__init__,調用了哪一個父類的__init__方法,就繼承了該父類的全部其它方法屬性,未被調用的父類,則不繼承該父類的方法屬性。3d

'''
1.組合:在一個類中以另一個類的對象做爲數據屬性,稱爲類的組合
'''
class School:
    def __init__(self,name,add):
        self.name=name
        self.add=add

class Course:
    def __init__(self,name,price,priod,school):
        self.name=name
        self.price=price
        self.priod=priod
        self.school=school  #傳入一個類,這樣就構成了一個組合,一類中包含了另外一個類

s1=School('清華','北京')
s2=School('科大','合肥')

c1=Course('python','1w','3mon',s1) #這就是組合,大類中包含小類
c2=Course('linux','2w','4mon',s2)

print(c1.school.name)
print(s1,'\n',c1.__dict__['school'])#打印 s1內存地址,地址相同

'''
 2. 繼承:新建的類能夠繼承一個或多個父類,父類又可稱爲基類或超類,新建的類稱爲派生類或子類
     python中類的繼承分爲:單繼承和多繼承
'''
class Father:
    money=100   #繼承類的屬性和方法
    def __init__(self,name):
        self.name=name
        print('這是爸爸【name=%s】類'%self.name)
    def Habit(self):
        print('爸爸【name=%s】的壞習性:愛抽菸'%self.name)
    def work(self):
        print('Father教學生')
class Mother:
    car='路虎'
    def __init__(self,age,national ):
        self.age=age
        self.national=national
        print('這是媽媽【age=%d】類'%self.age)
    def Hobby(self):
        print('媽媽【age=%d】的愛好是打球'%self.age)

class Son(Father,Mother): #能夠多繼承,但實例化時,若自身沒有__init__,則調用第一個父類的__init__,即Father.__init__
    def work(self):
       print('Son開汽車')


print(Father.__dict__)
print(Mother.__dict__)
print(Son.__dict__) #不包含父母類的任何屬性{'__module__': '__main__', 'work': <function Son.work at 0x000000000225A0D0>, '__doc__': None}

f=Father('大明')#建立Father對象,調用__init__實例化一個f對象,返回:這是爸爸【name=大明】類
m=Mother(30,'美國人')# 這是媽媽【age=30】類

print(Son.__base__)#__base__只查看從左到右繼承的第一個父類,<class '__main__.Father'>
print(Son.__bases__)#__bases__,查看全部父類,(<class '__main__.Father'>, <class '__main__.Mother'>)

s=Son('小明')#先調用本身的__init__,沒有則調用繼承的第一個父類,Father.__init__實例化一個s對象,故返回:這是爸爸【name=小明】類,

print(s.name,s.car,s.money)#能調用父母類的靜態數據屬性,小明 路虎 100
s.Habit()#能調用父類的方法屬性,爸爸【name=小明】的壞習性:愛抽菸
s.work()#Son開汽車---->方法名相同,並不會改寫父類的方法,
f.work()#Father教學生---->父類方法不變

s.Hobby()#出錯,AttributeError: 'Son' object has no attribute 'age',由於實例化時調用的是第一個父類Father.__init_
View Code

 

class Grandpa:
    language='英語'
    def tell(self):
        print('Grandpa會講%s'%self.language)

class Son1(Grandpa,Mother):
    def job(self):
        print('Son1 is a driver')
s1=Son1(15,'中國')
s1.Hobby()#這是媽媽【age=15】類,媽媽【age=15】的愛好是打球,Grandpa類沒有.__init__,就調用Mother.__init__
print(Son1.mro())#繼承順序:[<class '__main__.Son1'>, <class '__main__.Grandpa'>, <class '__main__.Mother'>, <class 'object'>]
View Code

 總結:類中的方法屬性都是與具體對象綁定的,而數據屬性無具體對象綁定,因此,在多繼承中,只有實例化了父類,即調用了父類的__init__方法後,才能調用該父類的其它方法屬性,而沒  有被實例化的父類,則不會繼承其方法屬性,但具備其數據屬性。至於@staticmethod的類工具包,既不綁定類又不綁定對象的方法屬性,是能繼承的。@classmethod,類方法,也是被類繼承。code

相關文章
相關標籤/搜索