面向对象的三大特性:今天主要讲的继承 (继承 ,多态,封装)
先抽象 》》》 后继承
单继承
继承 和抽象 语法:父类 子类
继承与重用
子类可以使用父类的名字(变量和方法)
继承与派生
子类在父类的基础上又新创建了自己需要的方法和属性
父类有的 子类没有 -----子类对象直接调用 就会直接执行父类的方法
父类有的 子类也有------子类对象调用 直接执行子类中的方法
想在子类中使用父类的名字: 父类名字 . 或者 super()去调用
多继承
# 语法
# 接口
# 新式类和经典类
# 新式类中
# 所有的多继承关系寻找方法的顺序 - 遵循广度优先算法
# 继承object
# mro方法
# super : super不是单纯的找父类,而是遵循mro顺序的
# 经典类
# python2.x
# 不主动继承object
# 经典类在找父类中方法的过程中 遵循 —— 深度优先
# 不提供mro方法和super
----------------------------------------------------------------------------------------------------------------------------------
猫类 : 属性 : 名字,品种,食物 方法 : 叫,抓老鼠,吃,喝 狗类 : 属性 : 名字,品种,食物 方法 : 叫,看家,吃,喝 class Animal: def __init__(self,name,kind,food,language): self.name = name self.kind = kind 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('看家')
阿猫 = Cat('阿猫','橘猫','牛杂','喵喵')
print(阿猫.name)
阿猫.drink()
阿猫.eat()
阿猫.yell()
阿狗 = Dog('阿狗','土狗','阿猫','汪汪')
print(阿狗.name)
阿狗.drink()
阿狗.eat()
阿狗.yell()
继承
父类也叫超类 基类 :Animal
子类也叫派生类: Cat Dog
继承与重用 : 父类中所有的属性 和 方法都可以被子类 使用!
派生
class Animal: def __init__(self,name,kind,food,language): print('in animal') self.name = name self.kind = kind 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,kind,food,language,eye_color): print('in Cat') self.eye_color = eye_color # 派生属性 Animal.__init__(self,name,kind,food,language) # super().__init__(name,kind,food,language) def catch_mouse(self): # 派生方法 print('抓老鼠') def eat(self): # 不仅执行了父类中的基础功能,还完成了特殊的功能 Animal.eat(self) # super().eat() self.weight = 10 class Dog(Animal): def look_after_house(self): print('看家') def eat(self): # Animal.eat(self) super().eat() self.drink() 阿猫 = Cat('阿猫','橘猫','牛杂','喵喵','绿色') print(阿猫.eye_color) print(阿猫.food) 阿猫.catch_mouse() 阿猫.eat() print(阿猫.weight)
当子类当中有要被调用的方法的时候,子类的对象会直接选择子类中的方法,变量, 父类中的方法不会被自动执行。
父类名 . 方法名(self,...)
super(). 方法名(...)
帮助我们在子类中调用父类中的同名方法
抽象类: 工作中 公司有使用抽象类 来定 开发的命名规则
# 支付功能 from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): # 模板的功能 @abstractmethod # abstractmethod是一个装饰器,装饰器怎么用?放在函数/类的上一行 def pay(self):pass @abstractmethod def shouqian(self):pass class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元'%money) class Wechatpay(Payment): def pay(self,money): print('使用微信支付了%s元'%money) class ApplePay(Payment): def pay(self,money): print('使用applepay支付了%s元' % money) def pay(obj,money): obj.pay(money) p = Payment()
规范
多人开发、复杂的需求、后期的扩展
手段 来帮助我们完成规范
抽象类
抽象类是一个规范,它基本不会实现什么具体的功能,抽象类是不能被实例化
要想写一个抽象类
from abc import ABCMeta,abstractmethod
在这个类创建的时候指定 metaclass = ABCMeta
在你希望子类实现的方法上加上一个 @abstractmethod装饰器
使用抽象类
继承这个类
必须实现这个类中被@abstractmethod装饰器装饰的方法
多继承;
不是所有语言都支持多继承 java
c++ 支持多继承
# 天鹅 飞 游泳 走路 # 老虎 走路 游泳 # 鹦鹉 飞 说话 走路 # class Animal: # def __init__(self,name): # self.name = name # def talk(self): # print('%s说话了'%self.name) # # def swim(self): # print('%s在游泳'%self.name) # # def fly(self): # print('%s在飞'%self.name) # # def walk(self): # print('%s在走路'%self.name) 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(SwimAnimal,WalkAnimal): pass class Swan(SwimAnimal,WalkAnimal,FlyAnimal): pass class Parrot(FlyAnimal,WalkAnimal): def talk(self): print('%s说话了'%self.name) swan = Swan('天鹅') swan.fly() swan.walk()
接口类: 借口 Interface 借口可以被多继承
新式类:
在python3.x 版本中 所有类都是新式类
所有新式类都有一个默认的父类 :object
python 2.7
经典类 和 新式类 并存
class Student:pass # 经典类
class Student(object):pass
继承了object的类就是新式类
在py3中所有的类都是新式类
在py2中既有新式类又有经典类
多继承的顺序 在新式类和经典类之间的区别
新式类中
所有的多继承关系寻找方法的顺序 - 遵循广度优先算法
继承object
mro方法
super : super不是单纯的找父类,而是遵循mro顺序的
经典类
python2.x
不主动继承object
经典类在找父类中方法的过程中 遵循 —— 深度优先
不提供mro方法和super