什么是继承,在生活中,子承父业,父亲和儿子就是继承的关系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