zoukankan      html  css  js  c++  java
  • 继承、抽象类、多继承

    # 继承的引子
    # 假设我们现在有一个游戏,游戏中有这些具体的事物(对象 ): 梅西、奥巴马、史努比、史派克、小猪配齐、猪八戒。
    # 采取面向对象设计的方法,是要对游戏中的具体对象,进行分门别类的抽象,抽取中相似对象的共同特征和行为来,作为一种规范,
    # 一种模板来,梅西和奥巴马,它们的相似,具有人的特征,因此,我们把它们归为一类,即人类,就抽象出人类这一概念来了。
    # 史努力和史派克 具有共同的特征和行为,我们把它们归为一类,并取名为狗类,完成具体到综合的第一次抽象,而小猪配齐和希猪八戒,
    # 它们两个具体的事物,又具有共性的东西,因此将它们归为一类,并取名为猪类。
    # 以上,通过对抽取相似具体事物的共同特征,归为一类,完成了事物的第一层抽象。
    # 梅西、奥巴马、史努比、史派克、小猪配齐、猪八戒 ===》 人类 、狗类 、 猪类 # 基本的分类
    # 人类 、狗类 、 猪类 ===》 经过再一次抽象,抽象出 动物类。
    # 因此面向对象的过程,就是由具体 到 抽象 的过程。从宏观上,概念上 统领相似事物。抽象的层次,越高,能够描述和规范的事物就越多。
    # # 猫类:
    # 属性: 名字,品种,食物
    # 方法: 叫,抓老鼠,吃,喝
    # 狗类:
    # 属性: 名字,品种,食物
    # 方法:叫,看家,吃,喝
    # 人类:
    # 属性:名字,品种,食物
    # 方法:说话,工作,吃,喝
    # 虽然,我们从具体的事物,抽象出三个类别,但是我们发现,这三类之间,还有共同的代码,没有提高代码的重用性。
    # 于是乎,我们可以将三个类别的共同代码,再抽取出来,建立一个类别,比如说叫动物类,它让猫类、狗类、人类隶属于这个类,
    # 也就具有这个类的属性。
    # 那么用puthon代码如何实现呢?

    # 定义 一个 Animal() 的父类
    class Animal: # 父类,超类,基类
    def __init__(self,name,kind,food,language):
    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): # 派生类
    def catch_mouse(self):
    print("抓老鼠")

    class Dog(Animal): # 派生类

    def __init__(self,name,kind,food,language,eye_color): # 子类重写父类的方法,并通过super()方法,调用父类的同名方法
    self.eye_color = eye_color # 派生属性
    super().__init__(name,kind,food,language) # self ,不用传,会自动传
    def swim(self): # 派生方法
    print("游泳")

    def look_afte_home(self):
    print("看家")

    class Human(Animal): # 派生类
    def __init__(self): # 这里子类对父类的方法,进行了重写,即覆盖了父类,此时父类的同名方法,对子类就不可见了。
    self.walk_way = "直立行走"
    def work(self):
    print("工作")


    # 在继承关系中,被继承的类,我们称之为超类/基类/父类, : 比如上面的 Animal类
    # 继承的类,叫做子类/派生类: 比如上面的 Cat, Dog, Person


    # 继承与重用:是同一个事物的两方面,类的继承就是了为提高代码的重用性,提高代码的重用性,除了函数,类就是别外一种的实现方式。
    # 比如说:写了两个类或多个类,它们有共同的代码或逻辑,这时候就可以为它们创建一个父类,把共同的代码或逻辑放到父类里,这时通过继承
    # 就实现了代码的重用性。
    # 继承与重用,父类中的所有方法和属性都被子类中使用了。
    阿猫 = Cat("阿猫","花猫","鱼","喵喵")
    阿猫.yell()
    阿猫.eat()
    阿猫.drink()
    print(阿猫.name)

    yellDog = Dog("黄狗","土狗","骨头","汪汪","蓝色")
    yellDog.eat()
    yellDog.drink()
    yellDog.yell()
    print(yellDog.name)

    xiaomin = Human() # 因为子类对父类的 __init__方法,进行了重写,除了self以外,没有参数,不需要手动传参。
    print(xiaomin.walk_way)
    yellDog.swim()

    # 总结:当子类当中有要被调用的方法 和 属性的时候,子类的对象会直接选择子类中的方法、变量,父类中的同名方法不会被自动执行。
    # 如果我们既想要执行子类中方法,也想要执行父类中的同名方法,那么需要在子类的方法中调用父类的方法:有两种方式:
    # 父类名.方法名(...)
    # super().方法名(...)

    # 面试题:

    class Foo:
    def __init__(self): # 初始化对象实例的函数,此函数仅在调用 类名() 时执行一次
    self.func() # 对象调用
    def func(self):
    print('in Foo')

    class Son(Foo):
    # def func(self):
    # print("in Son")
    pass

    s1 = Son() # 创建了一个Son类的对象实例,并赋值给对象引用 s1。过程是,在内存中开辟一个对象空间,根据对象所属的直接类的类
    #对象指针 找寻 __init__方法执行,子类没有,在父类中寻找,找到将对象传递参数self,执行 __init__函数体,执行self.func()语句,
    # 对象执行一个方法,先在对象所属直接类中,找到,直接执行,没有找到,再到父类找,所以此处是打印 in 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'
    # 结论:始终注意,那个对象调用 ,self就是哪个对象

    # 抽象类
    # 工作中 公司使用抽象类 ,来规范 开发的规则。
    # 源码 别人使用抽象类

    from abc import ABCMeta,abstractmethod # 从 abc 这个外部模块中,导入 ABCMeta 类 和 abstracmethod这个用于装饰函数的装饰器

    class Payment(metaclass=ABCMeta): # 给类的元类,传递一个关键字参数
    @abstractmethod
    def pay(self):pass # 抽象方法,仅有定义,没有方法的实现

    @abstractmethod
    def shouqian(self):pass # 假如,把这两行的注释打开,如果子类不实现这个方法,程序会报错
    # a = Alipay()
    # TypeError: Can't instantiate abstract class Alipay with abstract methods shouqian
    def abstract(self):
    print("我继承抽象类")

    class Alipay(Payment):
    def pay(self,money):
    print("使用支付宝支会了%s元" % money)
    def shouqian(self,money):
    print("使用收款方式收到%s元" % money)
    class Wechatpay(Payment):
    def pay(self,money):
    print("使用微信支付了%s元" % money)
    def shouqian(self,money):
    print("使用收款方式收到%s元" % money)
    class Applepay(Payment):
    def pay(self,money):
    print("使用applepay支付了%s元" % money)
    def shouqian(self,money):
    print("使用收款方式收到%s元" % money)

    # def pay(obj,money):
    # obj.pay(money)

    a = Alipay()
    a.pay(100)
    a.shouqian(2000)

    a.abstract() # 抽象类,也可以有普通方法,子类继承
    wechat = Wechatpay()
    wechat.pay(260)
    wechat.shouqian(489)

    apple = Applepay()
    apple.pay(159)
    apple.shouqian(6000)

    # 以上多个子类,继承同一个抽象类,子类必须去实现抽象类中用@abstractmethod装饰器装饰的方法,否则会报错。
    # 实现了不同的对象,调用相同的方法

    # 在上面的基础上,我们来定义 一个 统一的函数,也可以叫接口

    def 付钱(obj,money):
    obj.pay(money)
    # 这样,func()就是一个统一的支付接口
    付钱(wechat,1600)
    付钱(a,3500)

    def 收钱(obj,money):
    obj.shouqian(money)
    收钱(a,10000)
    收钱(apple,30000)

    # p = Payment() # 抽象类 , 不能实例化 TypeError: Can't instantiate abstract class Payment with abstract methods pay, shouqian


    # 总结: 抽象类 是一种 规范
    # 多人开发、复杂的需求、后期的扩展
    # 手段,来帮助我们完成规范。

    # 抽象类 如何创建
    # 抽象类是一个规范,它基本上不会实现什么具体的功能,抽象类是不能被实例化的。
    # 要想写一个抽象类的步骤:
    # from abc import ABCMeta,abstractmethod
    # 在创建这个类的时候,指定 metaclass = ABCMeta
    # 在你希望子类实现的方法上加一个 @abstractmethond 装饰器
    # 使用抽象类:
    # 继承这个类
    # 必须实现这个类中被 @abstractmehond 装饰器装饰的方法
  • 相关阅读:
    大型网站技术架构(七)网站的可扩展性架构
    【Spark深入学习 -15】Spark Streaming前奏-Kafka初体验
    结合案例深入解析模板方法设计模式
    android开发之自定义View 详解 资料整理 小冰原创整理,原创作品。
    1309:【例1.6】回文数(Noip1999)
    jQuery dataTables四种数据来源[转]
    CYQ.Data 轻量数据层之路 使用篇-MProc 存储过程与SQL 视频[最后一集] H (二十八)
    CRM系统项目总结
    同源策略:JSONP和CORS
    forms表单与modelfrom使用
  • 原文地址:https://www.cnblogs.com/chris-jia/p/9557264.html
Copyright © 2011-2022 走看看