面向对象之继承

一.什么是继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或者超类,新建的类又被成为派生类或子类

python中类的继承分为:单继承和多继承

 1 class ParentClass1:  #定义父类
 2     pass
 3 
 4 class ParentClass2:  #定义父类
 5     pass
 6 
 7 
 8 class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
 9     pass
10 
11 class SubClass2(ParentClass1,ParentClass2):  #python支持多继承,用逗号分隔开多个父类
12     pass

查看继承的方法

SubClass2.__bases__  # __base__之查看从左到右的第一个父类,而__bases__查看的是所有

如果没有指定基类,默认继承的是object类

二.继承与抽象(先抽象再继承)

抽象就是抽取类似或者说比较像的部分

抽象分为两个层次:

  1.将一些对象比较像的部分抽取成类

  2.将抽取出来的类中比较像的部分再抽取成父类

继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方法去表达抽象的结构

三.继承与复用性

class Animal:

    def __init__(self,name,ad,hp):
        self.name = name
        self.ad = ad
        self.hp = hp

    def eat(self):
        print(f'{self.name}吃东西!')


class Person(Animal):
    pass

class Dog(Animal):
    pass

p1 = Person('杨铚炎',1,10)
d1 = Dog('养只狗',10,100)
p1.eat()
d1.eat()

因为Person与Dog类有很多相似的地方,所以创建一个基类Animal, Person与Dog类都继承Animal,这样就实现了代码的复用性。大大的节省了编程的工作量。

四.派生

当然字类也可以提案加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性与父类重名,那么调用新增的属性时,就与自己为准了。

class Animal:

    def __init__(self,name,ad,hp):
        self.name = name
        self.ad = ad
        self.hp = hp

    def eat(self):
        print(f'{self.name}吃东西!')


class Person(Animal):

    def attack(self,obj):
        print(f'{self.name}攻击{obj.name}')

    def eat(self):
        super().eat()
        print(f'{self.name}吃饱了!')

class Dog(Animal):

    def bite(self,obj):
        print(f'{self.name}咬了{obj.name}')

p1 = Person('杨铚炎',1,10)
d1 = Dog('养只狗',10,100)
p1.eat()  #在本对象的方法中引用与其重名的父类方法
d1.eat()  #调用父类的
p1.attack(d1) #自己新的方法
d1.bite(p1)    #自己新的方法
super(Person,p1).eat() #直接调用父类的eat()方法

通过继承建立了派生类与基类之间的关系,当类之间有很多相同的功能时,提取这些功能作为基类,用继承比较好。

五.抽象类与接口类

接口类

继承有两种用途:

   1.继承基类的方法,并且做出自己的改变或者扩展(代码复用)

  2.声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口功能,子类继承接口类,并且实现接口中的功能

下面展示第二种用途:

 1 from abc import ABCMeta,abstractmethod
 2 
 3 class Payment(metaclass=ABCMeta):  #抽象类(接口类)
 4     @abstractmethod
 5     def pay(self,money):pass  #制定一个规范  必须要按照规范
 6 
 7 class Alipay(Payment):
 8     def pay(self,money):
 9         print(f'使用支付宝支付了{money}元')
10 
11 class Jdpay(Payment):
12     def pay(self, money):
13         print(f'使用京东支付了{money}元')
14 
15 class Wechatpay(Payment):
16     def weixinpay(self,money):  #没有按照规范,在实例化对象的时候会报错
17         print(f'使用微信支付了{money}')
18 
19 def pay(obj,money):
20     obj.pay(money)
21 
22 w = Wechatpay()  #实例化对象的时候报错
23 a = Alipay()
24 j = Jdpay()
25 pay(a,200)
26 pay(j,100)

继承的第二种含义非常重要,它又叫“接口继承“。

接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

为什么要使用接口:

  接口提取了一群类共同的函数,可以把接口当作一个函数的集合。

  然后让字类去实现接口中的函数。这么做的意义在于归一化,什么叫归一化,就是只要基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

  归一化,让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能,这极大的降低了使用者的使用难度。

抽象类

抽象类需要系欸住模块来实现  ,抽象类是一个特殊的类,他的特殊在于只能被继承,不能被实例化。

1 from abc import ABCMeta,abstractmethod
2 class Payment(metaclass=ABCMeta)
3     @abcstractmethod
4     def pay(self,money):pass
万般皆下品,唯有读书高!
原文地址:https://www.cnblogs.com/s686zhou/p/11243041.html