面向对象的三大特性 - 继承
阅读目录
什么是继承?
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
单继承和多继承
python中类的继承分为:单继承和多继承
class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
查看继承
>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类 (<class '__main__.ParentClass1'>,) >>> SubClass2.__bases__ (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
子类使用父类的方法
class Animal: def __init__(self,name,hp,ad): self.name = name self.hp = hp self.ad = ad class Person(Animal): def __init__(self,name,sex,hp,mp,ad): super().__init__(name,hp,ad) self.sex = sex # 派生属性 self.mp = mp # 派生属性 def attack(self,dog): print('%s攻击了%s'%(self.name,dog.name)) dog.hp -= self.ad class Dog(Animal): def __init__(self,name,kind,hp,ad): super().__init__(name,hp,ad) self.kind = kind # 派生属性 def bite(self,person): print('%s咬了%s'%(self.name,person.name)) person.hp -= self.ad alex = Person('alex','不详',10,10,0.1) hei = Dog('小黑','中华田园犬',999,1.1) print(hei.__dict__)
总结:
- 子类中有,父类中没有 : 用子类的
- 父类中有,子类中没有 : 用父类的
- 子类\父类中都有 : 默认情况下用子类的不用父类的
- 既想用父类又想用子类 : 父类名.方法名(子类对象), super().方法名()
- 子类\父类中都没有 : 报错
继承的面试题
class Base: def __init__(self): self.func() def func(self): print('in base') class Son(Base): def func(self): print('in son') s = Son()
执行结果:
in son
归一化设计
归一化设计 : 从原来的面向对象编程 -->面向函数编程.降低了用户的使用成本
def pay_func(person,payway,money): if payway == 'alipay': per = AliPay(person) #此处实例化一个对象 elif payway == 'wechatpay': per = WeChatPay(person) elif payway == 'ApplePay': per = ApplePay(person) per.pay(money) #对象直接调用pay这个动态属性,并传一个money这个参数
抽象类
单继承的形容,并且在单继承中可以在方法中写python代码
规定:Payment 就是一个规范类,这个类存在的意义不在于实现实际的功能,而是为了约束所有的子类必须实现pay的方法
Payment : 抽象类
pay = Payment() # 抽象类: 不能实例化
抽象类主要就是作为基类/父类,来约束子类中必须实现的某些方法
抽象类的特点:
- 必须在类定义的时候指定metaclass = ABCMeta
- 必须在要约束的方法上方加上@abstractmethod方法
from abc import ABCMeta,abstractmethod #(抽象方法)
class Payment(metaclass=ABCMeta): # metaclass 元类 metaclass = ABCMeta表示Payment类是一个规范类
@abstractmethod # @abstractmethod表示下面一行中的pay方法是一个必须在子类中实现的方法
def pay(self):pass
@abstractmethod
def back(self):pass # 退款功能
class ApplePay(Payment):
def pay(self):
pass
def back(self):
pass
接口类
python
抽象类 : 抽象类中的方法可以写一些具体的py代码(规范)
单继承 多继承
java
不支持多继承,新的概念 接口 Interface
和抽象类几乎一模一样的功能 :
只定义一个接口名字(基类名),内部定义子类必须实现的方法
接口支持多继承
接口内部的所有方法都不能写具体的代码,只能用pass代替
接口类 : 更接近java中的接口的概念
python中由于有了抽象类的多继承,不需要接口的概念了
一个基类写出来被子类多继承了 : 接口类
并且在方法中只写pass(你可以选择性的满足)
from abc import ABCMeta,abstractmethod class Fly_Animal(metaclass=ABCMeta): @abstractmethod def fly(self): print('爷会飞') class Swim_Animal(metaclass=ABCMeta): @abstractmethod def swim(self): pass class Walk_Animal(metaclass=ABCMeta): @abstractmethod def walk(self): pass class Swan(Fly_Animal,Swim_Animal,Walk_Animal): def fly(self): super().fly() print('飞') def walk(self):print('走') def swim(self):print('游') class Tiger(Walk_Animal,Swim_Animal): def walk(self):print('走') def swim(self):print('游') class Parrot(Fly_Animal,Walk_Animal): def fly(self):print('飞') def walk(self):print('走') def talk(self):print('说')