继承
作业回顾
1 基于圆形类实现一个圆环类,要求接收参数 外圆半径和内圆半径 2 # 完成方法 :计算环形面积和环形周长(公式自己上网查) 3 # 要求,借助组合,要求组合圆形类的对象完成需求 4 5 # class Annulus: 6 # def __init__(self,inner_r,outer_r): 7 # self.inner_r = inner_r 8 # self.outer_r = outer_r 9 # class Girth: 10 # def __init__(self,annulus): 11 # from math import pi 12 # self._girth = 2 * pi * (annulus.inner_r + annulus.outer_r) 13 # self._area = pi * (annulus.outer_r**2 - annulus.inner_r**2) 14 # 15 # R10 = Annulus(7,10) 16 # G10 = Girth(R10) 17 # print(G10._girth) 18 # print(G10._area)
老师的答案
1 # from math import pi 2 # class Circle: 3 # def __init__(self,r): 4 # self.r = r 5 # def area(self): 6 # return 3.14*self.r**2 7 # def perimeter(self): 8 # return 2*3.14*self.r 9 10 # class Ring: 11 # def __init__(self,outer_r,inner_r): 12 # outer_r,inner_r = (outer_r,inner_r) if outer_r > inner_r else (inner_r,outer_r) 13 # self.out_c = Circle(outer_r) 14 # self.in_c = Circle(inner_r) 15 # def area(self): 16 # return self.out_c.area() - self.in_c.area() 17 # def perimeter(self): 18 # return self.out_c.perimeter() + self.in_c.perimeter() 19 # r = Ring(10,8)
为什么这么写?
程序里有两个需求 :和圆形相关,和环形相关,求环形相关的内容的时候用到了圆形的公式 若出现的是圆柱形类,圆锥类
新内容
继承
-
单继承
-
解决代码的重复
-
继承语法:class 子类名(父类名):pass
1 # class A: 2 # pass 3 # class B(A): 4 # pass
B继承A。A是父类,超类,基类;B是子类,派生类。
-
子类可使用父类什么内容?
-
方法
-
静态变量
1 # class Animal: 2 # def __init__(self,name): 3 # self.name = name 4 # def eat(self): 5 # print('%s is eating'%self.name) 6 # def drink(self): 7 # print('%s is drinking'%self.name) 8 # def sleep(self): 9 # print('%s is sleeping'%self.name) 10 # class Cat(Animal): 11 # def climb_tree(self): 12 # print('%s is climbing'%self.name) 13 14 # class Dog(Animal): 15 # def house_keep(self): 16 # print('%s house keeping'%self.name) 17 18 # 小白 = Cat('小白')
寻址顺序:先开辟空间,空间里有一个类指针-->指向自己的类
调用init,对象在自己的空间中没找到init,自己类中也没找到
找父类中的init
-
-
当子类与父类的方法重名时,我们只用子类的方法而不会调用父类的方法
1 # class Animal: 2 # def __init__(self,name): 3 # self.name = name 4 # def eat(self): 5 # print('%s is eating'%self.name) 6 # def drink(self): 7 # print('%s is drinking'%self.name) 8 # def sleep(self): 9 # print('%s is sleeping'%self.name) 10 # 11 # class Cat(Animal): 12 # def eat(self): 13 # print('%s吃猫粮'%self.name) 14 # 15 # def climb_tree(self): 16 # print('%s is climbing'%self.name) 17 # 18 # 小白 = Cat('小白') 19 # 小白.eat() # 小白吃猫粮
-
子类想要调用父类的方法的同时还想执行自己的同名方法,怎么做?
在子类的方法中调用父类的方法:父类名.方法名(self)
1 # def __init__(self,name,food): 2 # self.name = name 3 # self.food = food 4 # self.blood = 100 5 # self.waise = 100 6 # def eat(self): 7 # print('%s is eating %s'%(self.name,self.food)) 8 # def drink(self): 9 # print('%s is drinking'%self.name) 10 # def sleep(self): 11 # print('%s is sleeping'%self.name) 12 13 # class Cat(Animal): 14 # def eat(self): 15 # self.blood += 100 16 # Animal.eat(self) 17 # def climb_tree(self): 18 # print('%s is climbing'%self.name) 19 # self.drink() 20 21 # class Dog(Animal): 22 # def eat(self): 23 # self.waise += 100 24 # Animal.eat(self) 25 # def house_keep(self): 26 # print('%s is keeping the house'%self.name) 27 # 小白 = Cat('小白','猫粮') 28 # 小黑 = Dog('小黑','狗粮') 29 # 小白.eat() 30 # 小黑.eat() 31 # print(小白.__dict__) 32 # print(小黑.__dict__)
-
总结
子类的对象如果调用方法永远优先调用自己的
-
如果自己有就用自己的
-
自己没有就用父类的
-
自己有还想用父类的话:直接在子类方法中输入:父类名.方法名(self)
-
例一:下面代码的输出?
1 # class Foo: 2 # def __init__(self): 3 # self.func() # 在每一个self调用func的时候,我们不看这句话是在哪里执行,只看self是谁 4 # 5 # def func(self): 6 # print('in foo') 7 # 8 # class Son(Foo): 9 # def func(self): 10 # print('in son') 11 # 12 # Son() 13 14 # in son
例二:如果想给狗和猫定制个性的属性
1 # class Animal: 2 # def __init__(self,name,food): 3 # self.name = name 4 # self.food = food 5 # self.blood = 100 6 # self.waise = 100 7 # def eat(self): 8 # print('%s is eating %s'%(self.name,self.food)) 9 # def drink(self): 10 # print('%s is drinking'%self.name) 11 # def sleep(self): 12 # print('%s is sleeping'%self.name) 13 # class Cat(Animal): 14 # def __init__(self,name,food,eye_color): 15 # Animal.__init__(self,name,food) # 调用了父类的初始化,去完成一些通用属性的初始化 16 # self.eye_color = eye_color # 派生属性 17 18 # 猫 : eye_color眼睛的颜色 19 # 狗 : size型号 20 # 小白 = Cat('小白','猫粮','蓝色') 21 # print(小白.__dict__)
-
-
多继承
-
有一些语言不支持多继承:java;但python支持
-
一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找
例:
1 # class B: 2 # def func(self):print('in B') 3 # class A: 4 # def func(self):print('in A') 5 # 6 # class C(B,A):pass 7 # C().func() # B在前,所以in B
-
-
知识点补充
-
object类 类祖宗
-
所有在python3当中的类都是继承object类的
-
object中有init
-
所有的类都默认的继承object
1 # class A:pass 2 # print(A.__bases__) 3 # class C:pass 4 # class B(A,C):pass 5 # print(B.__bases__) # 可以看到上一层所有父类
-
-
绑定方法和普通的函数
1 from types import FunctionType,MethodType 2 # FunctionType : 函数 3 # MethodType : 方法
isinstance type的区别:instance可以判断出父类即以上的类
1 # a = 1 2 # b = 'abc' 3 # print(isinstance(a,int)) 4 # print(isinstance(a,float)) 5 # print(isinstance(b,str))
1 # a = 1 2 # b = 'abc' 3 # print(type(a) is int) 4 # print(type(b) is str)
1 # class Cat: 2 # pass 3 # 小白 = Cat() 4 # print(type(小白) is Cat) 5 # print(isinstance(小白,Cat))
1 # class Animal:pass 2 # class Cat(Animal):pass 3 # 小白 = Cat() 4 # print(type(小白) is Cat) # True 5 # print(type(小白) is Animal) # False 6 # print(isinstance(小白,Cat)) # True 7 # print(isinstance(小白,Animal)) # True
类.调用他就是一个函数,对象.调用他就是一个方法
1 # class A: 2 # def func(self): 3 # print('in func') 4 # 5 # print(A.func) # 函数 6 # a = A() 7 # print(a.func) # 方法 8 # print(isinstance(a.func,FunctionType)) 9 # print(isinstance(a.func,MethodType)) 10 # print(isinstance(A.func,FunctionType)) 11 # print(isinstance(A.func,MethodType))
-
特殊的类属性
-
类名.
__name__
# 类的名字(字符串) -
类名.
__doc__
# 类的文档字符串(看注释) -
类名.
__base__
# 类的第一个父类(在讲继承时会讲) -
类名.
__bases__
# 类所有父类构成的元组(在讲继承时会讲) -
类名.
__dict__
# 类的字典属性 -
类名.
__module__
# 类定义所在的模块 -
类名.
__class__
# 实例对应的类(仅新式类中)
1 # print(A.__class__) # 所有类的类型都是type 2 # print(B.__class__) 3 # print(C.__class__)
-
-
pickle:可以存取对象
1 class Course: 2 def __init__(self,name,period,price): 3 self.name = name 4 self.period = period 5 self.price = price 6 7 # python = Course('python','6 moneth',21800) 8 # linux = Course('linux','5 moneth',19800) 9 # go = Course('go','4 moneth',12800) 10 import pickle 11 # with open('pickle_file','ab') as f: 12 # pickle.dump(linux,f) 13 # pickle.dump(go,f) 14 with open('pickle_file','rb') as f: 15 while True: 16 try: 17 obj = pickle.load(f) 18 print(obj.name,obj.period) 19 except EOFError: 20 break
-