美文网首页
面向对象的三大特征

面向对象的三大特征

作者: Snackk | 来源:发表于2018-08-28 19:47 被阅读0次
    • 当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
      [组合是"有"的关系,继承是"是"的关系] --->比如教授有生日,比如白马是马,人是动物
      1

    继承

    • 继承与抽象(先抽象再继承)
    • 抽象即抽取类似或者说比较像的部分。
    • 父类/超类/基类
    • 子类/派生类
    • 继承与重用 - 父类中所有的属性和方法都可以被子类使用
    • 子类调用属性和方法找不到会去父类去找------>继承

    派生

    • 当子类当中有要被调用的方法的时候,子类的对象会直接选择子类中的方法、变量,父类中的方法不会被自动执行
    • 如果我们既想要执行子类的方法,也想要执行父类的方法,那么需要在子类的方法中调用父类的方法[重点]:
    • 父类名.方法名(self,...) [用法同下]
    • super().方法名(...)
    • 帮助我们在子类中调用父类中的同名方法
    class Animal:
        def __init__(self,name,kind,food,language):
            print('in animal')
            self.name = name
            self.kind = kind
            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,kind,food,language,eye_color):
            print('in Cat')
            self.eye_color = eye_color    # 派生属性
            # Animal.__init__(self,name,kind,food,language)
            super().__init__(name,kind,food,language)
    
        def catch_mouse(self):   # 派生方法
            print('抓老鼠')
    
        def eat(self):           # 不仅执行了父类中的基础功能,还完成了特殊的功能
            Animal.eat(self)
            # super().eat()
            self.weight = 10
    
    class Dog(Animal):
        def look_after_house(self):
            print('看家')
    
        def eat(self):
            # Animal.eat(self)
            super().eat()
            self.drink()
    
    阿猫 = Cat('阿猫','橘猫','牛杂','喵喵','绿色')
    print(阿猫.eye_color)
    print(阿猫.food)
    阿猫.catch_mouse()
    阿猫.eat()
    print(阿猫.weight)
    

    2

    面试题

    class Foo:
        def __init__(self):
            self.func()
        def func(self):
            print('in Foo')
    
    class Son(Foo):
        def func(self):
            print('in Son')
    
    s1 = Son()
    
    class Foo:
        Country = 'China'
        def func(self):
            print(self.Country)
    
    class Son(Foo):
        Country = 'English'
        def func(self):     # 走这个方法
            print(self.Country)
    
    s = Son()
    s.func()
    
    class Foo:
        Country = 'China'
        def func(self):  # 走这个方法
            print(self.Country)
    
    class Son(Foo):
        Country = 'English'
    
    s = Son()
    s.func()   # English
    
    class Foo:
        Country = 'China'
        def func(self):
            print(self.Country)
    
    class Son(Foo):pass
    
    s = Son()
    s.func()   # 'China
    

    运行结果:

    in Son
    English
    English
    China
    
    Process finished with exit code 0
    

    3

    抽象类

    from abc import ABCMeta,abstractmethod
    
    class Payment(metaclass=ABCMeta):   # 模板的功能
        @abstractmethod     # abstractmethod是一个装饰器,装饰器怎么用?放在函数/类的上一行
        def pay(self):pass
    
        @abstractmethod
        def shouqian(self):pass
    
    规范
    • 多人开发、复杂的需求、后期的扩展

    • 手段 来帮助我们完成规范

    • 抽象类
      抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的
      从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
      抽象类就是从一堆类中抽取相同的内容而来的
      python也有抽象类的概念但是同样需要借助模块实现.
      抽象类是一个规范,它基本不会实现什么具体的功能,抽象类是不能被实例化

      • 要想写一个抽象类
        • from abc import ABCMeta,abstractmethod
        • 在这个类创建的时候指定 metaclass = ABCMeta
        • 在你希望子类实现的方法上加上一个 @abstractmethod装饰器
      • 使用抽象类
        • 继承这个类
        • 必须实现这个类中被@abstractmethod装饰器装饰的方法

    4

    多继承

    • 子类继承父类逻辑上要行得通

    • 父类的属性和方法属于子类

    • 多继承问题
      在继承抽象类的过程中,我们应该尽量避免多继承;
      而在继承接口的时候,我们反而鼓励你来多继承接口

    # 天鹅  飞 游泳 走路
    # 老虎  走路 游泳
    # 鹦鹉  飞 说话 走路
    
    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(SwimAnimal,WalkAnimal):
        pass
    
    class Swan(SwimAnimal,WalkAnimal,FlyAnimal):
        pass
    
    class Parrot(FlyAnimal,WalkAnimal):
        def talk(self):
            print('%s说话了'%self.name)
    
    swan = Swan('天鹅')
    swan.fly()
    swan.walk()
    
    

    5

    接口类

    • 抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计

    • 在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念

    • 抽象类的本质还是类,指的是一组类的相似性

    在抽象类中,我们可以对一些抽象方法做出基础实现;
    而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现

    java c#
    不允许多继承
    接口 Interface  接口可以被多继承
    
    Interface FlyAnimal:  # 规范继承我的类必须实现这个方法
        def fly():pass
    
    class Tiger(WalkAnimal,SwimAnimal):  继承了一个规范
        def walk():代码
        def swim():代码
    

    6

    钻石继承

    bases则是查看所有继承的父类
    base只查看类的第一个父类

    • 新式类
      在python3.x版本中 所有的类都是新式类
      所有的新式类都有一个默认的父类 : object

    • 在新式类中

      • 所有的多继承关系寻找方法的顺序 - 遵循广度优先算法
      • 继承object
      • mro方法:查找父类顺序 F.mro() #等同于F.__mro__
      • super : super不是单纯的找父类,而是遵循mro顺序的
    • 3种写法都一样
      class Person1:pass
      class Person2():pass
      class Person3(object):pass

    • 多继承的顺序
    • D,B,C,A
    class A:
        def func(self):
            print('A')
    
    class B(A):
        pass
        # def func(self):
        #     print('B')
    
    class C(A):
        pass
        # def func(self):
        #     print('C')
    
    class D(B,C):
        pass
        # def func(self):
        #     print('D')
    print(D.mro())
    d = D()
    d.func()
    
    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')
    
    D().func()
    B().func()
    

    结果

    A
    C
    B
    D
    A
    B
    
    Process finished with exit code 0
    

    python 2.7

    • 经典类
      python2.x
      不主动继承object
      经典类在找父类中方法的过程中, 遵循 —— 深度优先
      不提供mro方法和super

    经典类 和 新式类 并存
    class Student:pass # 经典类
    class Student(object):pass#新式类

    总结:继承了object的类就是新式类

    相关文章

      网友评论

          本文标题:面向对象的三大特征

          本文链接:https://www.haomeiwen.com/subject/zboqwftx.html