继承和接口与归一化设计

继承和接口与归一化设计

返回首页

继承

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

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass

print(ParentClass1.__bases__)
print(SubClass1.__bases__)
print(SubClass2.__bases__)

继承与抽象

抽象即是抽取类似或者比较像的部分,抽象分为两个层次。

1、将奥巴马和梅西这俩对象比较像的部分抽取成类。

2、将人、猪、狗这三个类比较像的部分抽取成父类

抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

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

class Aniaml:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def walk(self):
        print('%s is walking' %self.name)

    def say(self):
        print('%s is saying' %self.name)

class People(Aniaml):
    pass

class Pig(Aniaml):
    pass

class Dog(Aniaml):
    pass

p1 = People('obama',50) #people没有name和age,但是people继承了animal,所以可以使用animal的name和age
print(p1.name)
print(p1.age)
p1.walk()

继承可以解决重用性。

上面的例子就说明了重用性,在people类中,不用再写walk和say,在继承的父类animal中调用即可。

派生

派生就是将类共有的属性(特征)和函数(技能)单独取出,作为一个父类后,子类里在添加的属性和函数,就是派生。派生出类自己的东西。 

class Hero:
    def __init__(self, nickname,aggressivity,life_value):
        self.nickname = nickname
        self.aggressivity = aggressivity
        self.life_value = life_value
    def attack(self, enemy):
        print('Hero attack')

class Garen(Hero):
    camp = 'Demacia'
    def attack(self, enemy): #self=g1,enemy=r1
        # self.attack(enemy) #g1.attack()
        Hero.attack(self,enemy)    #用父类里的attack,参数是Hero里的attack的参数。这里的self是g1,enemy是r1
        print('from garen attack')

    def fire(self):
        print('%s is firing' % self.nickname)

class Riven(Hero):
    camp = 'Noxus'

g1 = Garen('garen', 18, 200)
r1 = Riven('rivren', 18, 200)
g1.attack(r1)
print(g1.camp)
print(r1.camp)
g1.fire()

组合

组合是类与类之间有的关系, 当类之间有着明显不同,并且较小的类是较大的类所需要的组件时,用组合比较好。

接口与归一化设计

在python中,没有接口的概念。而接口的概念,简单的说就是对外的入口。所以在python中,要实现接口的效果,只能用继承去模拟。

在继承中,父类不用去实现具体的功能,而是在子类中,具体的去实现。

class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
    def read(self): #定接口函数read
        pass

    def write(self): #定义接口函数write
        pass

class Txt(Interface): #文本,具体实现read和write
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的写入方法')

class Sata(Interface): #磁盘,具体实现read和write
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的写入方法')

class Process(Interface):
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的写入方法')

t1=Txt()
s1=Sata()
p1=Process()
t1.read()
t1.write()
s1.read()
s1.write()
p1.read()
p1.write()

抽象

import abc
#抽象类:本质还是类,与普通类额外的特点的是:加了装饰器的函数,子类必须实现他们
class Animal(metaclass=abc.ABCMeta):
    tag='123123123123123'
    @abc.abstractmethod
    def run(self):
        pass
    @abc.abstractmethod
    def speak(self):
        pass

class People(Animal):
    def run(self):
        pass

    def speak(self):
        pass

peo1=People()
print(peo1.tag)

继承的顺序

继承的顺序分为python2和python3。

在python2中,经典类和新式类的继承方式是不同的。

py2中,经典类的多继承顺序是:优先深度查找。新式类的多继承顺序是:优先广度查找。

在py3中,只有新式类,所以py3只有广度优先查找。

新式类:

 #新式类的继承,在查找属性时遵循:广度优先
class A(object):
    def test(self):
        print('from A')
class B(A):
    def test(self):
        print('from B')
class C(A):
    def test(self):
        print('from C')
class D(B):
    def test(self):
        print('from D')
class E(C):
    def test(self):
        print('from E')
class F(D,E):
    def test(self):
        print('from F')
f1=F()
f1.test()

print(F.__mro__)
print(F.mro())

#广度优先:F->D->B->E->C->A->object

经典类:

#python2中经典类的继承,在查找属性时遵循:深度优先
class A:
    number = 10
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    def test(self):
        print('from F')

f1=F()
f1.test()
print(f1.number)

###F->D->B->A->E->C

super函数

子类调用父类的方法,用super方法。

除了在子类中,用类名.的方法调用父类方法外,还可以用super方法。

#在python3中
class People:
    def __init__(self,name,sex,age):
        self.name=name
        self.age=age
        self.sex=sex

    def walk(self):
        print('%s is walking' %self.name)

class Chinese(People):
    country='China'
    def __init__(self,name,sex,age,language='Chinese'):
        # self.name=name
        # self.sex=sex
        # self.age=age
        # People.__init__(self,name,sex,age)
        super(Chinese,self).__init__(name,sex,age) #super()相当于一个对象,super().__init__相当于是调用对象的绑定方法。也就是调用父类的绑定方法。
        self.language=language

    def walk(self,x):
        super().walk()
        print('子类的x',x)

c=Chinese('egon','male',18)
print(c.name,c.age,c.sex,c.language)
c.walk(123)

---------- END ---------

原文地址:https://www.cnblogs.com/george92/p/14573909.html