day18 继承 抽象类 多继承 新式类 经典类

内容概览
  类的静态属性
  什么是继承?
  多继承
  新式类
  经典类

面向对象基础知识回顾
类的静态属性
请记住:对象名.静态属性 = 一个新值
通过对象名去修改类的静态属性,结果是在对象的空间中创建了一个属性,而不能修改类中的属性
class Foo:
    count = 0
    def __init__(self):
        Foo.count += 1

print(Foo.count)
f1 = Foo()
print(f1.count)
#而对象f1 里面是没有属性 只有一个类对象指针指向Foo,在f1找不到count 到类里面去寻找count
f2 = Foo()
print(f2.count)
f3 = Foo()
print(f3.count)
f4 = Foo()
print(f4.count)
f5 = Foo()
print(f5.count)
print(Foo.count)

  

 
0
1
2
3
4
5
5

  

记住
只要是对象的某个属性被直接赋值,那么对象的名称空间一定发生改变
因此只要是静态属性就用类名来操作
class Foo:
    count = [0]

f1 = Foo()
f1.count[0] += 1
print(f1.count[0])
print(Foo.count[0])

f1.count = [2]
print(f1.count[0])
print(Foo.count[0])

  

1
1
2
1

  

 


正式进入 类的继承
继承里面的概念
父类/超类(super)/基类(base) #Animal
子类/派生类 #Cat Dog
class Animal:
    def __init__(self,name,breed,food,language):
        self.name = name
        self.breed = breed
        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('看家呢!!!')

  


#什么是继承? 以及重用
#父类中所有的属性和方法都可以被子类使用

cat1 = Cat('阿猫','橘猫','猫粮','喵喵')
print(cat1.name)
cat1.eat()
cat1.drink()
cat1.yell()
cat1.catch_mouse()


dog1 = Dog('旺财','田园犬','狗粮','汪汪')
print(dog1.name)
dog1.yell()
dog1.drink()
dog1.eat()
dog1.look_after_house()

  

阿猫
吃猫粮
抓老鼠!!
喝水!!!
喵喵叫!!!
旺财
汪汪叫!!!
喝水!!!
吃狗粮
看家呢!!!

  



class Animal:
    def __init__(self,name,breed,food,language):
        self.name = name
        self.breed = breed
        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,breed,food,language,eye_color,weight):
        Animal.__init__(self,name,breed,food,language)#使用父类名.__init__继承Animal的所有属性 参数self依然需要
        self.eye_color = eye_color#子类所独有的静态属性
        self.weight = weight

    def catch_mouse(self):#派生的方法 父类中没有的 子类或者能够所独有的
        print('抓老鼠!!')
    def eat(self):
        #Animal.eat(self)#执行了父类中的方法
        super().eat()
        self.weight += 10#子类的属性发生变化

class Dog(Animal):
    def __init__(self,name,breed,food,language,eye_color):
        super().__init__(name,breed,food,language)#使用super().__inter__继承Animal的所有属性 super 就是通过self找到的 所有不需要输入self
    def look_after_house(self):
        print('看家呢!!!')

  



当子类中有 被调用的便令和方法,子类的对象会直接调用子类中的方法,变量,父类中的方法不会执行

cat1 = Cat('阿猫','橘猫','猫粮','喵喵','蓝色',0)
cat1.eat()#即执行了父类的中功能eat 还完成了Cat特有的功能吃一顿饭之后weight += 10
print(cat1.weight)
cat1.eat()
print(cat1.weight)

  

吃猫粮
10
吃猫粮
20

  


总结一下
子类中调用父类同名的方法
在子类中写上 super().方法名 父类名.方法名
记住super()后面一定要加()
例如 super().eat() Animal.eat()

class Foo():
    def __init__(self):
        self.func()
    def func(self):
        print('in Foo')

class Son(Foo):
    def func(self):
        print('in Son')
s1 = Son()#实例化对象
s1.func()

  

 
class Foo:
    country = 'China'
    def func(self):
        print(self.country)
class Son(Foo):
    country = 'English'
S = Son()
S.func()

  


#抽象类
#抽象类是一个规范,基本不会实现什么功能,抽象了也不能被实例化
#怎么写一个抽象类
#from abc importABCMeta,abstractmethod

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

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

def payment(obj,money):
    obj.pay(money)
a = Alipay()
a.pay(100)
b = Wechatpay()
b.pay(200)
payment(a,100)
payment(b,200)

  

使用支付宝支付了100元
使用微信支付了200元
使用支付宝支付了100元
使用微信支付了200元

  

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

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

class Applepay():
    def fuqian(self,money):
        print('使用Apple支付了%s元' % money)


def payment(obj,money):
    obj.pay(money)
a = Alipay()
a.pay(100)

b = Wechatpay()
b.pay(200)

payment(a,100)
payment(b,200)

c = Applepay()
payment(c,100)

  

 
Applepay' object has no attribute 'pay

  





抽象类
from  abc import  ABCMeta,abstractmethod
class Pament(metaclass=ABCMeta):
    @abstractmethod   #abstractmethod是一个装饰器,放在函数或者类的上一行
    def pay(self):pass

    @abstractmethod
    def fuqian(self):payment()
class Wechatpay():
    def pay(self, money):
        print('使用微信支付了%s元' % money)

class Applepay():
    def pay(self,money):
        print('使用Apple支付了%s元' % money)
def payment(obj,money):
    obj.pay(money)
c = Applepay()
payment(c,100)

  



怎么写一个抽象类???
from abc import ABCMeta,abstractmethod
    在这个类创建的时候指定
metaclass=ABCMeta
    在希望子类实现的方法上加一个装饰器@abstractmethod        

  



如何使用抽象类???
继承这个类
必须实现这个类中被@abstractmethod装饰器装饰的方法

老虎 走 游泳
天鹅 飞 走 游泳
鹦鹉 说话 飞 走
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(WalkAnimal,SwimAnimal):
    pass
class Swan(WalkAnimal,SwimAnimal,FlyAnimal):
    pass
swan1 = Swan('天鹅')
print(swan1.name)
swan1.walk()
swan1.fly()
swan1.swim()

  

天鹅
天鹅在走路!!
天鹅正在飞翔!!!
天鹅在游泳!!

  


经典类与 新式类

在py3中所有的类都是新式类
所有的新式类都有一个共同的父类(祖先类):object
class Person1:pass
class Person2():pass
class Person3(object):pass
print(Person1.__bases__)
print(Person2.__bases__)
print(Person3.__bases__)

  

(<class 'object'>,)
(<class 'object'>,)
(<class 'object'>,)

  


在py2.7中 经典类与新式类并存
class Student:
    pass
class Student(object):#继承了object的就是新式类
    pass

  




新式类中多继承 关系 查找的顺序 遵循广度优先



#练习题
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()
        print('D')
print(D.mro())
D().func()
遵循广度优先,先是以及以往上找,func函数D-->B-->C-->A找到之后再往回退打印各自里面的东西
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
A
C
B
D

  


总结
新式类
  多继承关系寻找的方法遵循--广度优先
  继承object
  mro方法
  super方法不是单纯的找父类,而是遵循mro顺序



经典类
  但是在py2中遵循的是深度优先,一条道走到底,
  不主动继承object
  不提供mro super方法

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








猜你喜欢

转载自www.cnblogs.com/cavalier-chen/p/9550352.html