1. 程式人生 > >python學習之-繼承與派生

python學習之-繼承與派生

什麼是繼承

繼承是一種新建類的方式,新建的類稱之為子類/派生類,被繼承的類稱之為父類\基類\超類

繼承描述的是一種遺傳的關係,父類的屬性可以被子類訪問到

為何要繼承

解決類與類之間程式碼冗餘的問題

如何用繼承

在python中繼承的特點:

1. 在python中一個子類可以同時繼承多個父類

2. 在python3如果一個類沒有指明繼承的類,預設繼承object,在python2如果一個類沒有指明繼承的類,不會預設繼承object

 

Python中的類分成兩種

新式類

但凡繼承了object類的子類,以及該子類的子子類都是新式類

經典類

沒有繼承object類的子類,以及該子類的子子類都是經典類

在python3全都是新式類

在python2中才去分經典類與新式類

  class Parent1(object): #Python2中類定義傳入引數object就是新式類
    pass

繼承例項

class Parent1(object): #這是父類 ,傳入一個object引數,是為了相容Python2,所以如果要向下相容這裡必須寫
  pass

class Parent2(object): #這是父類
  pass

class Sub1(Parent1):  #這是子類單繼承
  pass

class Sub2(Parent1,Parent2): #這是子類,而且是多繼承


  pass

PS:如何繼承,就是子類把父類當做引數傳入下面的程式碼中

 

檢視繼承的方法__bases__

print(Sub1.__bases__)

print(Sub2.__bases__)

檢視父類的繼承

print(Parent1.__bases__)

print(Parent2.__bases__)

PS:可以看到是一個類object,在python3如果一個類沒有指明繼承的類,預設繼承object

 

繼承例項

class Animal:

    def eat(self):
        print("%s 吃 " %self.name)

    def drink(self):
        print ("%s 喝 " %self.name)

    def shit(self):
        print ("%s 拉 " %self.name)

    def pee(self):
        print ("%s 撒 " %self.name)


class Cat(Animal):

    def __init__(self, name):
        self.name = name
        self.breed = '貓'

    def cry(self):
        print('喵喵叫')

class Dog(Animal):

    def __init__(self, name):
        self.name = name
        self.breed='狗'

    def cry(self):
        print('汪汪叫')


# ######### 執行 #########

c1 = Cat('小白家的小黑貓')
c1.eat()

c2 = Cat('小黑的小白貓')
c2.drink()

d1 = Dog('胖子家的小瘦狗')
d1.eat()

 

繼承的背景下屬性查詢

在單繼承背景下新式類經典類屬性查詢都一樣: 物件->物件的類->父類->父父類...

class Foo:
  # xxx=222
  pass

class Bar(Foo):
  # xxx=111
  pass

obj=Bar()
  # obj.xxx=0
  print(obj.xxx)

PS:查詢xxx屬性,如果物件裡面沒有,則去類裡面找,類裡面沒有則去父類找,父類沒有則去object裡面找然後會報錯,這一點新式類和經典類都一樣

 

練習:self.f1是查找了父類的還是自身的
class Foo:
  def f1(self):
    print('Foo.f1')

def f2(self):
  print('Foo.f2')
  self.f1() # obj.f1()


class Bar(Foo):
  def f1(self):
    print('Bar.f1')

obj = Bar()
obj.f2()

首先建立了一個物件呼叫的是bar類,然後查詢f2屬性,bar類下沒有,則去父類中查詢,父類中有f2這個屬性,則查詢到,然後f2屬性下又呼叫了自身下的屬性f1,所以最終查詢的是自己的f1屬性,而不是父類下的,因為一開始查詢f2的時候自身沒有,因為繼承了父類的屬性,所以又去父類中查詢,父類中的f2下呼叫的是自身,因為一開始查詢的時候就將自身傳入了父類中去查詢,所以最後呼叫的是自己

 

在子類派生的新方法中重用父類的功能

方式一

class OldboyPeople:
school = 'Oldboy'
def __init__(self,name,age,gender):
self.name=name
self.age=age
self.gender=gender

class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)

class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, gender,level): #如果父類引數滿足不了,則可以重新派生定義一個新的,這裡就是定義一個新的派生,用內建方法__init__
OldboyPeople.__init__(self,name, age, gender) #這就是子類派生的新方法中重用父類功能,類呼叫物件就是呼叫函式,所以少一個引數都不行,這裡就是重用父類的功能
self.level=level #這一段是需要自己增加的程式碼

def score(self,stu,num):
stu.score=num
print('老師[%s]為學生[%s]打了分[%s] ' %(self.name,stu.name,num))

stu1=OldboyStudent('王大炮',18,'male') #初始化學生的資訊
print(stu1.__dict__) #檢視有沒有初始化成功

tea1=OldboyTeacher('Egon',18,'male',10) #初始化老師的資訊,如果有重用父類功能,這裡也要傳入相應的引數
print(tea1.__dict__) #檢視有沒有初始化成功