什麼是繼承,在生活中,子承父業,父親和兒子就是繼承的關係python
在python中,父類和子類(派生類),父類和子類只有在繼承的時候纔會產生linux
如下面例子爲例,繼承爲了拿到父類全部東西code
class Parent_Poo: def __init__(self,first_name,money,car,house): self.first_name = first_name self.money = money*0.5 print('繼承財產扣掉一半') self.car = car self.house = house def find_wife(self): print('{self.first_name}先生找到妻子白富美') class Son_Foo(Parent_Foo): pass sf = Son_Foo('🐖',1000,'tesla','上海湯臣一品一棟') # 實例化一個兒子對象 print(sf.first_name) print(sf.money) print(sf.car) print(sf.house) sf.find_wife() # 由於sf 是一個對象,全部不用傳find_wife的參數self,self是對象sf自己 Parent_Foo.find_wife(111) # Parent_Foo是一個類,類調用方法,須要傳入參數self,能夠隨便什麼值
爲何要用繼承: 減小重複,全部的兒子均可以用這個類,少寫東西htm
# 人是動物,狗也是動物,咱們就能夠定義一個動物類,動物共同具備的特徵 class Animal(): # 正常 class Animal: 就能夠了,加() 結果同樣,只是若是用繼承的話,就加括號,而且括號內加入須要繼承的類,能夠多個 def __init__(self,height,weight): self.height = height self.weight = weight def jiao(self): print(self.__class__.__name__,'叫') # self.__class__.__name__打印的是類的名稱 class Xingxing(): def sleep(self): print('睡覺') class People(Animal,Xingxing): def read(self): print('read') def jiao(self): print('jiao') aobama = People(170,120) # 實例化對象,須要傳入初始設置參數 height,weight aobama.jiao() # jiao 屬性查找順序,先對象,再類,再父類,在父類的父類,菱形廣義查找(python3) aobama.sleep() meixi = People(168,140) meixi.jiao() # jiao 同上 class Dog(Animal): def eat(self): print('eat') shinubi = Dog(40,50) shinubi.jiao() # print(self.__class__.__name__,'叫') 屬性查找順序
不推薦使用繼承,當你繼承多個的時候,功能和功能之間會混亂,頂多繼承一個對象
繼承後查找順序: 先本身,再類,再父類,再父類的父類,不找多各種最後繼承的同一個類,直接去找下一個父類,廣度優先blog
下面作一個小練習,理解一個self參數的含義繼承
class Foo: def f1(self): print('Foo.f1') def f2(self): print('Foo.f2') self.f1() class Bar(Foo): def f1(self): print('Bar.f1') b = Bar() #實例化一個對象 print(b.__dict__) # {} 初始對象__dict__都爲{} b.f2() # 想想 打印結果什麼? b.f2()-->本身內部找,b中沒有f2方法,去繼承類Foo找-->找到Foo中的f2方法-->打印 Foo.f2-->執行self.f1()-->self 爲對象自己b,實爲b.f1()-->去b中找f1()-->能找到f1,打印Bar.f1 b.f2() # Foo.f2 Bar.f1
class Animal(): def __init__(self,height,weight): self.height = height self.weight = weight def jiao(self): print(self.__class__.__name__,'叫') class XingXing(): def __init__(self, gender): self.gender = gender def sleep(self): print('睡覺')
類的派生: 添加新的屬性的同時還有繼承父類的全部東西ip
print('*'*50) # 方法一: class People(Animal,Xingxing): def __init__(self,name,age) self.name = name self.age = age def read(self): print('read') def jiao(self): print('jiao') peo = People('gll',18) # 實例化的時候自動調用__init__ # 繼承就是爲了使用父類的屬性 Animal.__init__(peo,180,140) print(peo.__dict__) # 這樣使用起來很是麻煩 print('*'*50) class People: def __init__(self,name,age,height,weight): # 'gll', 18, 160, 110 Animal.__init__(self,height,weight) # Animal.__init__(peo,160,110) self.name = name self.age = age def read(self): print('read') def jiao(self): print('jiao') peo = People('gll',18,160,110) # 實例化的時候自動調用__init__ print(peo.__dict__) # 發現: 方法一不須要繼承也能夠作到
print('*' * 50) # 方法二: class Xingixing(Animal): def __init__(self,weight,height,gender): super().__init__(weight,height) self.gender = gender # 派生: 繼承父類屬性的同時增長新的屬性,而後使用super.__init__() # 引出方法二,方法二至關於對方法一進行了一層封裝 class People(Xingxing): def __init__(self,name,age,height,weight,gender): super().__init__(height,weight,gender) # 別人規定的語法 self.name = name self.age = age def read(self): print('read') def jiao(self): print('jiao') peo = People('gll',18,160,110,'femal') # 實例化的時候自動調用__init__ print(peo.__dict__)
# 方法三: print('*' * 50) # python2中必須指定繼承誰的__init__ (python2能用的,python3基本也是能夠用) class People(Animal): def __init__(self,name,age,height,weight): super(People,self).__init__(height,weight) # 別人規定的語法,python2中這樣寫 self.name = name self.age = age def read(self): print('read') def jiao(self): print('jiao') peo = People('gll',18,160,110) # 實例化的時候自動調用__init__ print(peo.__dict__)
組合: 就是組合在一塊兒 # 簡單的選課系統 class People: def __init__(self,name,gender): self.name = name self.gender = gender def eat(self): print(f'{self.name}開始吃了') class Student(People): def __init__(self,student_id,name,gender): self.student_id = student_id super(Student,self).__init__(name,gender) def choose_course(self,course): self.course = course print(f'{self.name}選課{course.name}成功') class Teacher(People): def __init__(self,level,name,gender): self.level = level super(Teacher,self).__init__(name,gender) def score(self,student,course,score): print(f'老師{self.name}給{student.name}課程{course.name}打分{score}') class Course: def __init__(self,name,price): self.name = name self.price = price class Admin(People): def create_course(self,name,price): course = Course(name,price) print(f'管理員{self.name}建立了課程{name}') return course # 課程 # python = Course('Python', '8888') # linux = Course('Linux', '6666') # 學生 zhubajie = Student('01', 'zhubajie', 'male') sunwukong = Student('02', 'sunwukong', 'male') # 老師 nick = Teacher('1', 'nick', 'male') tank = Teacher('2', 'tank', 'female') # 管理員 egon = Admin('egon', 'male') # 業務邏輯 # 1. 建立課程 python = egon.create_course('python', '8888') print(python.__dict__) linux = egon.create_course('linux', '6666') print(linux.__dict__) # 2. 學生選擇課程 zhubajie.choose_course(python) # 3. 老師給學生打分 nick.scored(zhubajie,python,'0')
經典類 和新式類get
在python3當中會默認繼承object類
在python2當中不會默認繼承object類,必須得本身手動添加
新式類: 只要繼承了object類的就是新式類,python3當中全部的類都是新式類
經典類: 沒有繼承object類的就是經典類,只有python2當中的經典類
當繼承爲菱形繼承的時候,經典類和新式類搜索某一個屬性的順序會不同
class G: def test(self): print('from G') class F(G): def test(self): print('from F') class E(G): # def test(self): # print('from E') pass class D(G): def test(self): print('from D') class C(F): def test(self): print('from C') class B(E): # def test(self): # print('from B') pass class A(B, C, D): # def test(self): # print('from A') pass a = A() a.test() for i in A.__mro__: # A.mro() print(i)
在新式類中: 當遇到菱形繼承時,會以廣度優先查找
在經典類中: 當遇到菱形繼承時,會以深度優先查找
普通繼承就是正常順序找
多態: 多種狀態,只要你們能繼承同一種東西A,這些東西就是A的多態
水: 液態/固態/氣態
動物: 人/夠/貓
import abc class Animal(metaclass = abc.ABCMeta): # 不推薦使用 def __inint__(self,height,weight): self.height = height self.weight = weight def sleep(self): print('我在睡覺') @abc.abstractmethod def speak(self): print(self, '開始叫了') @abc.abstractmethod def eat(self): print(self, '開始吃了') class People(Animal): def speak(self): print('開始叫了') def eat(self): print(self, '開始吃了') class Dog(Animal): def speak(self): print('開始叫了') def eat(self): print(self, '開始吃了') class Cow(Animal): def speak(self): print('開始叫了') def eat(self): print(self, '開始吃了') class Foo(Animal): def speak(self): pass f = Foo(1,2) f.sleep() # 實例化對象 peo = People(180, 140) dog = Dog(50, 100) cow = Cow(100, 200) # peo.speak() # dog.speak() # cow.speak() # sheep.speak() # mao.speak() # peo.eat() # dog.eat() # 鴨子類型: 長得像鴨子,叫聲也像鴨子,就是鴨子(只要有speak和eat這兩個方法,那他就是動物類) # 對於咱們這個例子:你只要有speak方法/有eat方法,我不管你怎麼定義這個類,你就是動物的一種形態,你這樣才能用動物的方法,不然沒法使用動物的方法
# python 3.7 作的更新,定義類簡單不少 from dataclasses import dataclass @dataclass class Point: x: float y: float z: float = 0.0 # p = Point(1.5, 2.5) # print(p) # produces "Point(x=1.5, y=2.5, z=0.0)" from dataclasses import dataclass @dataclass class zhuangbei: price: int aggrev: int life_value: int bc = zhuangbei(9,100,10) class duolandun(zhuangbei): pass class BlackCleaver(zhuangbei): pass # print(bc) f = BlackCleaver(0,100,10) print(f)
查看dataclass的用法,能夠參考下面的網址
dataclass使用:http://www.javashuo.com/article/p-ujeczsjd-gz.html