Day17 python基礎---面向對象三大特性---繼承

一,繼承和抽象概念python

  1.抽象:即抽取相似或者比較像的部分。抽象只是分析和設計的過程當中,一個動做或者說一種技巧,經過抽象能夠獲得類。面試

     抽象分紅兩個層次:算法

    1)將奧巴馬和梅西這倆對象比較像的部分抽取成類;編程

    2)將人,豬,狗這三個類比較像的部分抽取成父類。c#

        2.繼承:是基於抽象的結果,經過編程語言去實現它,確定是先經歷抽象這個過程,才能經過繼承的方式去表達出抽象的結構。app

     

二,單繼承編程語言

       1.語法:父類,子類函數

          父類/超類/基類spa

          子類/派生類設計

  2.繼承與重用

           父類全部的屬性和方法均可以被子類使用

class Animal:  #父類/超類/基類 
    def __init__(self,name,kind,food,language):
        self.name = name
        self.kind = kind
        self.food = food
        self.language = language

    def yell(self):
        print('%s叫'%self.language)
    def eat(self):
        print('%s吃%s'%(self.name,self.food))
    def drink(self):
        print('%s喝'%self.name)

class Cat(Animal):  #子類/派生類 
    def catch(self):
        print('%s抓老鼠'%self.name)

class Dog(Animal):  #子類/派生類 
    def look_after_house(self):
        print('%s看家'%self.name)

# 繼承與重用 -  父類中全部的屬性和方法均可以被子類使用了
阿貓 = Cat('阿貓','橘貓','貓糧','喵喵')
阿狗 = Dog('阿狗','二哈','狗糧','汪汪')
print(阿貓.name)
阿貓.drink()
阿貓.eat()
阿貓.catch()
阿貓.yell()

  3.繼承與派生

          派生:子類在父類的基礎上又新建立了本身須要的方法和屬性

              1.父類有的子類沒有:子類對象直接調用,就會直接執行父類的方法

              2.父類有的子類也有:子類對象調用,直接執行子類中的方法,若在子類中使用父類的屬性和方法:父類名、super()去調用

class Cat(Animal):   #Animal的派生類
    def __init__(self,name,kind,food,language,eye_color):
        self.eye_color = eye_color   #派生屬性
        Animal.__init__(self,name,kind,food,language)
        #super().__init__(name,kind,food,language)
    def catch(self):    #派生方法
        print('%s抓老鼠'%self.name)
    def eat(self):    # 不只執行了父類中的基礎功能,還完成了特殊的功能
        Animal.eat(self)
        #super().eat()
        self.weight = 10
# 當子類當中有要被調用的方法的時候,子類的對象會直接選擇子類中的方法、變量,父類中的方法不會被自動執行
# 若是咱們既想要執行子類的方法,也想要執行父類的方法,那麼須要在子類的方法中調用父類的方法:
#   父類名.方法名(self,...)
#   super().方法名(...)
#   幫助咱們在子類中調用父類中的同名方法
# 面向對象特性之繼承--面試題
#當self去調用某個方法的時候,不要看self在哪一個類裏,要看self究竟是誰
class Foo: def __init__(self): self.func() def func(self): print('in Foo') class Son(Foo): def func(self): print('in Son') s1 = Son() ################## class Foo: Country = 'China' def func(self): print(self.Country) class Son(Foo): Country = 'English' def func(self): # 走這個方法 print(self.Country) s = Son() s.func() #################### class Foo: Country = 'China' def func(self): # 走這個方法 print(self.Country) class Son(Foo): Country = 'English' s = Son() s.func() # English ######################### class Foo: Country = 'China' def func(self): print(self.Country) class Son(Foo):pass s = Son() s.func() # 'China'

  4.規範的編程模式:抽象類

        抽象類的概念:

   1.抽象類是一個規範,它基本不會實現什麼具體功能,抽象類是不能被實例化的

         2.工做中,有的公司源碼有使用抽象類開發的規則,在多人開發,複雜的需求,後期的擴展的場景中,使用抽象類來幫助咱們完成規範

# 抽象類語法
        # from abc import ABCMeta,abstractmethod
        # 在這個類建立的時候指定 metaclass = ABCMeta
        # 在你但願子類實現的方法上加上一個 @abstractmethod裝飾器

#抽象類的使用
        # 繼承這個類
        # 必須實現這個類(子類建立同名的方法)中被@abstractmethod裝飾器裝飾的方法
from  abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta):   # 模板的功能
    @abstractmethod       # abstractmethod是一個裝飾器,放在函數/類的上一行
    def pay(self):pass   #該抽象類的子類,都必須實現父類的方法,不然報錯

class Alipay(Payment):
    def pay(self,money):
        print('使用支付寶支付了%d'%money)

class wechatpay(Payment):
    def pay(self,money):
        print('使用支付寶支付了%d'%money)

def pay(obj,money):#構造函數存入對象和參數,自動調用類的方法
    obj.pay(money)

#TypeError: Can't instantiate abstract class Payment with abstract methods pay
#p = Payment()  #抽象類實例化會報錯
a = Alipay()
w = wechatpay()
pay(a,100)
pay(w,150)
#全部的對象的type都是創造這個對象類
class A:pass
obj = A()
type(obj) is A
#全部沒有指定metaclass的類的type都是type
#若是指定了metaclass,那麼這個類的type就是指定的metaclass的值
#類也是被創造出來的,type是創造類的機制,即元類是創造類的機制
#例:補全func:
#     - dir方法可以獲得當前文件中的全部成員
#     - 獲取handler中名字叫Base的成員
#     - 檢查其餘成員是不是Base類的子類(不包含Base),若是是則建立對象並添加到objs列表中。


class Base(object):pass

class F1(Base):pass

class F2(Base):pass

class F3(F2):pass

class F4(Base):pass

class F5(object):pass

class F6(F5):pass

import sys
def func():
    name_lst = dir(sys.modules[__name__])
    obj_list = []
    for name in name_lst:
        name_addr = getattr(sys.modules[__name__],name)
        print(type(name_addr))
        if type(name_addr) is type and issubclass(name_addr,Base) and name_addr is not Base:
            obj_list.append(name_addr())
    return obj_list
ret = func()
print(ret)

 

 

 

 

三,多繼承

       1.不是全部的語言都支持多繼承,例,jave,c#

        2.因爲python支持多繼承,因此python沒有接口類

        3.其餘不支持多繼承的語言的接口類,至關於只是繼承了一個規範,繼承接口類規範的類必須實現接口類的方法

#python的多繼承語法
class Parent1:pass
class Parent2:pass
class Son(Parent1,Parent2):pass
print(Son.__bases__)   #__bases__查看全部父類,__base__只查看從左到右繼承的第一個子類
class Animal:
    def __init__(self,name):
        self.name = name

class FlyAnimal(Animal):
    def fly(self):
        print('%s在飛'%self.name)

class WalkAnimal(Animal):
    def walk(self):
        print('%s在走路'%self.name)

class SwimAnimal(Animal):
    def swim(self):
        print('%s在游泳'%self.name)

class Tiger(SwimAnimal,WalkAnimal):
    pass

class Swan(SwimAnimal,WalkAnimal,FlyAnimal):
    pass

class Parrot(FlyAnimal,WalkAnimal):
    def talk(self):
        print('%s說話了'%self.name)

swan = Swan('天鵝')
swan.fly()
swan.walk()

  4.新式類和經典類

         #新式類:

         #全部的多繼承關係尋找方法的順序:遵循廣度優先算法

         #繼承object

         #mro方法

         #super:super()不是單純的找父類,而是遵循mro順序的    

          #經典類:

             #python2.x

        #不主動繼承object

        #經典類在找父類中方法的過程當中,遵循:深度優先

      #不提供mro方法和super()

# python 2.7
# 經典類 和 新式類 並存
# class Student:pass # 經典類
# class Student(object):pass

# 繼承了object的類就是新式類
# 在py3中全部的類都是新式類
# 在py2中既有新式類又有經典類

# 多繼承的順序 在新式類和經典類之間的區別
class A:
    def func(self):
        print('A')

class B(A):
    # pass
    def func(self):
        print('B')

class C(A):
    # pass
    def func(self):
        print('C')

class D(B,C):
    # pass
    def func(self):
        print('D')
print(D.mro())
d = D()
d.func()
相關文章
相關標籤/搜索