一、组合
1、一个类的对象作为另一个类的对象的属性
2、让两个类之间产生关系
3、增加类的功能,提高代码的重用性
总结:静态属性就是类的属性,所有的对象共享这个变量
对象名去修改类的属性,会在对象空间中又创建一个属性,而不能修改类中属性的值
操作静态属性应该用类名操作
当类中的属性发生改变的时候,而对象中没有同名的属性,方法的时候,对象使用属性名会跟着类中变量走
只要某个对象的属性被直接复制,那么一定是对象的命名空间发生变化
class Foo:
count = 0
def __init__(self):
Foo.count += 1
f1 = Foo()
f2 = Foo()
f3 = Foo()
print(Foo.count) # 3统计类调用了几次
class Fun1:
count = [0]
def __init__(self):
pass
f1 = Fun1()
f1.count[0] = 1
print(f1.count[0]) #1
print(Fun1.count[0]) #1
f1.count = 2
print(f1.count) #2
print(Fun1.count) #[1]
二、继承
1、重用性
父类中所有属性和方法都可以被子类使用
class Animal:
def __init__(self,name,age,food):
self.name = name
self.age = age
def eat(self):
print('%s吃%s' %(self.name,self.food))
def drink(self):
print('%s喝水' %(self.name))
class Dog(Animal):
def __init__(self,name,age,food):
super().__init__(name,age,food)
class Cat(Animal):
def __init__(self,name,age,food):
super().__init__(name,age,food)
dog1 = Dog('小黑',5,'狗粮')
dog1.eat()
car1 = Car('小花',3,'猫粮')
car1.drink()
2、派生
子类在父类的基础上又创建了自己需要的属性与方法
当子类中有要被调用的方法和变量的时候,子类的对象会直接选择子类中的方法和变量
父类中的方法不会被自动执行
如果我们既想要执行子类的方法,又想要执行父类的方法,那么需要在子类中调用父类的方法
父类名.方法名(self) super().方法名()
当self在调用某个方法时 ,不要看self在哪个类里,要看self是谁
class Animal: def __init__(self,name,food,language): self.name = name self.food = food self.language = language def eat(self): print('吃%s' %self.food) def drink(self): print('%s喝水' %self.name)class Dog(Animal): def look_after_house(self): print('看门') def eat(self): # super(Dog, self).eat() Animal.eat(self) self.drink()class Cat(Animal): def __init__(self,name,food,language,eye_color): self.eye_color = eye_color def eat(self): self.weight = 10 #派生属性 def catch_mouse(self): #派生方法 print('抓老鼠')xhei = Dog('小黑','狗粮','汪汪')xhua = Cat('小花','猫粮','喵喵','蓝色')xhei.eat()xhua.eat()print(xhua.weight)xhua.catch_mouse()
3、抽象
抽象类是一个规范,它基本不会实现具体的功能,抽象类不能被实例化
多人开发,复杂的需求,后期扩展
抽象类的语法:
from abc import ABCMeta,abstractmethod
在这个类创建的时候制定metaclass = ABCMeta
在你希望子类实现的方法上加一个@abstractmethod装饰器
使用抽象类
继承这个类
必须实现这个类中被@abstractmethod装饰器装饰的方法
from abc import ABCMeta,abstractmethodclass Payment(metaclass=ABCMeta): @abstractmethod def pay(self): passclass Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元' %money)class WechatPay(Payment): def pay(self,money): print('使用微信支付了%s元' %money)a = Alipay()a.pay(34)w = WechatPay()w.pay(29)
4、多继承
class Animal: def __init__(self,name): self.name = nameclass FlyAnial(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): passclass Swan(FlyAnial,WalkAnimal,SwimAnimal): passclass Parrot(FlyAnial,WalkAnimal): def talk(self): print('%s在说话' %(self.name))swan = Swan('天鹅')swan.fly()swan.walk()swan.swim()
5、经典类与新式类
在python3.x中所有的类都是新式类,默认继承object,继承顺序遵循广度优先原则
在python2.x中既有经典类,又有新式类,经典类的继成顺序遵循深度优先原则
只有继承了object的类才是新式类
只有在新式类中才有mro方法和super方法,super方法不是单纯的找父类,而是遵循mro
class A: def test(self): print('A')class B(A): def test(self): print('B')class C(B): def test(self): print('c')class D(C): def tets(self): print('d')class F(D,C): def test(self): print('f')print(F.mro()) #线性列表,继承顺序# [, , , # , , ]
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')D().func()B().func()#A C B D#A B