内容概览
类的静态属性
什么是继承?
多继承
新式类
经典类
面向对象基础知识回顾
类的静态属性
请记住:对象名.静态属性 = 一个新值
通过对象名去修改类的静态属性,结果是在对象的空间中创建了一个属性,而不能修改类中的属性
class Foo: count = 0 def __init__(self): Foo.count += 1 print(Foo.count) f1 = Foo() print(f1.count) #而对象f1 里面是没有属性 只有一个类对象指针指向Foo,在f1找不到count 到类里面去寻找count f2 = Foo() print(f2.count) f3 = Foo() print(f3.count) f4 = Foo() print(f4.count) f5 = Foo() print(f5.count) print(Foo.count)
0 1 2 3 4 5 5
记住
只要是对象的某个属性被直接赋值,那么对象的名称空间一定发生改变
因此只要是静态属性就用类名来操作
class Foo: count = [0] f1 = Foo() f1.count[0] += 1 print(f1.count[0]) print(Foo.count[0]) f1.count = [2] print(f1.count[0]) print(Foo.count[0])
1 1 2 1
正式进入 类的继承
继承里面的概念
父类/超类(super)/基类(base) #Animal
子类/派生类 #Cat Dog
class Animal: def __init__(self,name,breed,food,language): self.name = name self.breed = breed self.food = food self.language = language def yell(self): print('%s叫!!!'%self.language) def eat(self): print('吃%s'%self.food) def drink(self): print('喝水!!!') class Cat(Animal): def catch_mouse(self): print('抓老鼠!!') class Dog(Animal): def look_after_house(self): print('看家呢!!!')
#什么是继承? 以及重用
#父类中所有的属性和方法都可以被子类使用
cat1 = Cat('阿猫','橘猫','猫粮','喵喵') print(cat1.name) cat1.eat() cat1.drink() cat1.yell() cat1.catch_mouse() dog1 = Dog('旺财','田园犬','狗粮','汪汪') print(dog1.name) dog1.yell() dog1.drink() dog1.eat() dog1.look_after_house()
阿猫 吃猫粮 抓老鼠!! 喝水!!! 喵喵叫!!! 旺财 汪汪叫!!! 喝水!!! 吃狗粮 看家呢!!!
class Animal: def __init__(self,name,breed,food,language): self.name = name self.breed = breed self.food = food self.language = language def yell(self): print('%s叫!!!'%self.language) def eat(self): print('吃%s'%self.food) def drink(self): print('喝水!!!') class Cat(Animal):#Animal的派生类 def __init__(self,name,breed,food,language,eye_color,weight): Animal.__init__(self,name,breed,food,language)#使用父类名.__init__继承Animal的所有属性 参数self依然需要 self.eye_color = eye_color#子类所独有的静态属性 self.weight = weight def catch_mouse(self):#派生的方法 父类中没有的 子类或者能够所独有的 print('抓老鼠!!') def eat(self): #Animal.eat(self)#执行了父类中的方法 super().eat() self.weight += 10#子类的属性发生变化 class Dog(Animal): def __init__(self,name,breed,food,language,eye_color): super().__init__(name,breed,food,language)#使用super().__inter__继承Animal的所有属性 super 就是通过self找到的 所有不需要输入self def look_after_house(self): print('看家呢!!!')
当子类中有 被调用的便令和方法,子类的对象会直接调用子类中的方法,变量,父类中的方法不会执行
cat1 = Cat('阿猫','橘猫','猫粮','喵喵','蓝色',0) cat1.eat()#即执行了父类的中功能eat 还完成了Cat特有的功能吃一顿饭之后weight += 10 print(cat1.weight) cat1.eat() print(cat1.weight)
吃猫粮 10 吃猫粮 20
总结一下
子类中调用父类同名的方法
在子类中写上 super().方法名 父类名.方法名
记住super()后面一定要加()
例如 super().eat() Animal.eat()
class Foo(): def __init__(self): self.func() def func(self): print('in Foo') class Son(Foo): def func(self): print('in Son') s1 = Son()#实例化对象 s1.func()
class Foo: country = 'China' def func(self): print(self.country) class Son(Foo): country = 'English' S = Son() S.func()
#抽象类
#抽象类是一个规范,基本不会实现什么功能,抽象了也不能被实例化
#怎么写一个抽象类
#from abc importABCMeta,abstractmethod
支付
class Alipay(): def pay(self,money): print('使用支付宝支付了%s元'%money) class Wechatpay(): def pay(self, money): print('使用微信支付了%s元' % money) def payment(obj,money): obj.pay(money) a = Alipay() a.pay(100) b = Wechatpay() b.pay(200) payment(a,100) payment(b,200)
使用支付宝支付了100元 使用微信支付了200元 使用支付宝支付了100元 使用微信支付了200元
class Alipay(): def pay(self,money): print('使用支付宝支付了%s元'%money) class Wechatpay(): def pay(self, money): print('使用微信支付了%s元' % money) class Applepay(): def fuqian(self,money): print('使用Apple支付了%s元' % money) def payment(obj,money): obj.pay(money) a = Alipay() a.pay(100) b = Wechatpay() b.pay(200) payment(a,100) payment(b,200) c = Applepay() payment(c,100)
Applepay' object has no attribute 'pay
抽象类
from abc import ABCMeta,abstractmethod class Pament(metaclass=ABCMeta): @abstractmethod #abstractmethod是一个装饰器,放在函数或者类的上一行 def pay(self):pass @abstractmethod def fuqian(self):payment() class Wechatpay(): def pay(self, money): print('使用微信支付了%s元' % money) class Applepay(): def pay(self,money): print('使用Apple支付了%s元' % money) def payment(obj,money): obj.pay(money) c = Applepay() payment(c,100)
怎么写一个抽象类???
from abc import ABCMeta,abstractmethod 在这个类创建的时候指定 metaclass=ABCMeta 在希望子类实现的方法上加一个装饰器@abstractmethod
如何使用抽象类???
继承这个类
必须实现这个类中被@abstractmethod装饰器装饰的方法
老虎 走 游泳
天鹅 飞 走 游泳
鹦鹉 说话 飞 走
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(WalkAnimal,SwimAnimal): pass class Swan(WalkAnimal,SwimAnimal,FlyAnimal): pass swan1 = Swan('天鹅') print(swan1.name) swan1.walk() swan1.fly() swan1.swim()
天鹅 天鹅在走路!! 天鹅正在飞翔!!! 天鹅在游泳!!
经典类与 新式类
在py3中所有的类都是新式类
所有的新式类都有一个共同的父类(祖先类):object
class Person1:pass class Person2():pass class Person3(object):pass print(Person1.__bases__) print(Person2.__bases__) print(Person3.__bases__)
(<class 'object'>,) (<class 'object'>,) (<class 'object'>,)
在py2.7中 经典类与新式类并存
class Student: pass class Student(object):#继承了object的就是新式类 pass
新式类中多继承 关系 查找的顺序 遵循广度优先
#练习题
class A: def func(self): print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D') print(D.mro()) D().func()
遵循广度优先,先是以及以往上找,func函数D-->B-->C-->A找到之后再往回退打印各自里面的东西
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>] A C B D
总结
新式类
多继承关系寻找的方法遵循--广度优先
继承object
mro方法
super方法不是单纯的找父类,而是遵循mro顺序
经典类
但是在py2中遵循的是深度优先,一条道走到底,
不主动继承object
不提供mro super方法
class A: def func(self): print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D')