PYthon_面向对象-继承篇

继承分类

继承分为:

父类:基类、超类
子类:派生类

class father:pass

class gong(father):                                 #单继承
    def __init__(self,name,hobby,hp,ad):        
        self.name = name
        self.hobby = hobby
        self.hp = hp
        self.ad = ad

class Dog(gong,father):                             #多继承
    def func(self):
        print('%s攻击了' %self.name)

dog=Dog('笨笨','骨头',50,200)
dog.func()

print(gong.__bases__)
print(Dog.__bases__)

解释:

一个类中的属性被领一个属性所包含,比如A类是一个公共类,a类应用了A类的属性,那么A类就是a的父类,a就是A的子类。一个子类如果有一个子类,那么久是单继承,两个父类,那么就是多继承,

注意:

  1. 在Python3中,所有的自定义类都有一个父类,默认叫做object,可以使用__base__来显示
    print(gong.__bases__)
    print(Dog.__bases__)
    
  2. 如果是多继承,先看括号内第一个父级,然后算第二个、第三个……
  3. 在Python2.X存在经典类,就是父类没有object,如果继承了object那么就是新生类,Python3.X取消了经典类
  4. super参数在Python2新生类,必须传参数(子类、子类对象)
  5. 经典类在查找(遍历)的时候是深度优先算法,没有mro(查找优先级)方法;而新生类是按照广度优先算法训找

顺序(优先级)

首先先去子类的命名空间去寻找,如果子类命名空间没有那么就去父类的命名空间找,如果子类和父类同时拥有一个相同的属性,那么默认优先去找自己的子类找,

如果必须要去父类寻找,可以使用super() (super就是找到自己的父类,不需要手动传入self)

Animal.eat(alex)                    #指名道姓(写死、不常用)

super(Person,alex).eat()            #在类外面调用(不常用)

super().eat()                       #推荐(可在子类直接使用 或 赋给外面的直接调用)

例:

class Animal:
    def __init__(self,name,hp,ad):
        self.name = name
        self.hp = hp
        self.ad = ad
    def eat(self):
        print('+20',self.name)
        self.hp += 20

class Person(Animal):
    def __init__(self,name,hp,ad,sex):
        Animal.__init__(self,name,hp,ad)    
                                        # self 和Animal的self都是指向一个(一个方法内部两个相同的名字代表着一个
        self.sex=sex
    def attack(self,dog):
        print('%s攻击了%s' %(self.name,dog))
    def eat(self):
        super().eat()

class Dog(Animal):
    def __init__(self,name,hp,ad):
        # Animal.__init__(self,name,hp,ad)
        super().__init__(name,hp,ad)                    
        super(Dog,self).__init__(name,hp,ad)
    def attack(self,person):
        print('%s攻击了%s' %(self.name,person))

dog = Dog('笨笨',20,200)
zhe = Person('female',100,5,'gay')
print(zhe.__dict__)
print(dog.__dict__)                 
zhe.eat()                           #先找自己命名空间的eat,然后通过super调用父类的eat方法

例2:

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()   # B
        print('D')

d = D()
d.func()

广度优先算法

归一化设计

什么是归一化设计:

多个类的对象中拥有相同的方法或者功能,定制了一个特殊的函数,只需要将参数传入函数,即可完成调用。

接口类和抽象类

在Python中存在多继承,所以并没有接口类和抽象类的概念一样,从Java的规范而来,作用两者都是来约束子类中的方法,使其更加规范,注意:Python抽象类不能实例化

from  abc import abstractmethod,ABCMeta

class zhun(metaclass=ABCMeta):
    @abstractmethod
    def pay(self):pass

class Alipay(zhun):
    def pay(self,money):
        print('使用 支付宝 支付了%s元' %money)

class QQpay(zhun):
    def pay(self,money):
        print('使用 QQ 支付了%s元' %money)

class WXpay(zhun):
    def pay(self,money):
        print('使用 微信 支付了%s元' %money)

a=Alipay()
q=QQpay()
w=WXpay()

def func(z,money):                  
    z.pay(money)
func(w,100)

为了代码更加规范导入abc模块,如果没有加入pay方法就会报错,而且就算新加的方法如果没有pay方法实例化也依旧会报错!

多继承 例:

class FlyAnimal(metaclass=ABCMeta):         #定义父类
    @abstractmethod
    def fly(self):pass
    @abstractmethod
    def cal_flying_speed(self):pass
    @abstractmethod
    def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta):            #定义父类
    @abstractmethod
    def walk(self):pass
class SwimAnimal(metaclass=ABCMeta):            #定义父类
    @abstractmethod
    def walk(self):pass
class Tiger(WalkAnimal,SwimAnimal):
    def walk(self):pass
    def swim(self):pass
class Monkey(WalkAnimal)
    def walk(self):pass
    def climb(self):pass
class Swan(FlyAnimal,WalkAnimal,SwimAnimal):
    def swim(self):pass
    def walk(self):pass
    def fly(self):pass
    def cal_flying_height(self):pass
    def cal_flying_speed(self):pass
class Parrot(FlyAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass

需要注意的是,当多个类之间有相同的功能也有不同的功能的时候,应该采用多个接口类来进行分别的约束

接口隔离原则:
使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

http://www.cnblogs.com/Eva-J/articles/7293890.html#_label11

发表评论