zoukankan      html  css  js  c++  java
  • python--8、面向对象的深入知识

    面向对象的三大特性

      上一篇我们讲的主要内容都符合面向对象的封装特性。那么问题来了?面向对象难道只有封装性么?当然不是,作为一个这么难理解的东西,要是只有封装性都对不起我们死了这么多脑细胞!所以,晴天霹雳来了,面向对象有三大特性,他们分别是:封装、继承和多态

      好消息和好消息和好消息,好消息一:封装我们已讲完,所以三座大山我们已经移走了一座,好消息二:由于python的特殊性,多态的应用并不广泛,所以我们其实还有一座半就胜利了,好消息三:前面那两条好消息都是真的。闲话少叙,今天咱们就聊聊继承,移走一座是一座!

    正题——面向对象的继承性

      一、继承

      大学同学聚会,同桌吃饭,我们都是人,都有吃饭、喝饮料这些行为,但是毕业之后大家都做了不同的工作,有的当了会计、有的做了程序员,现在我们得到了描述这些同学这个需求,我们一看非常开心,我们可以实现呀,然后写下了下面左图的代码:

                                        

      我们看上面左侧的代码,这么写确实实现了我们的需求,但是,写了那么多行,真正不一样的只有黄色框框里面的内容,好在大学同学的职业都差不多,这要是高中聚会可就热闹了。这个时候,我们就想,有没有可能我们不重复写之前的代码,也实现同样的功能呢?当然啦!→_→右侧这段代码。看着就简洁了不少,这就是类的继承。现在你看着好像有点儿迷糊,没关系,这里只需要知道有一种简单的方法可以实现,这种写法就叫做继承。具体我们后面还要详细讲。

               

      我们来详细看看上面这张图,解释一下什么叫做继承,首先在最上面的黄框框里,我们定义了一个类叫做classmate,这个里面放了吃、喝两个方法,下面我们又定义了两个类,pythoner和accounting类,里面各写了一个occupation方法,打印出了人物的职业。我们看到,classmate类和我们之前见到的类并没什么不同,可是pythoner和accounting类定义的时候,我们看红框框里写了classmate类的类名,我们说,这样就实现了继承。pythoner和accounting类集成了classmate的所有属性和方法。

      说完了继承类的定义,我们再来看看实例化和调用,我们看上面右侧那张小图,我们分别实例化了两个对象,eva和sweet,注意看红框框里我们实例化的是pythoner和accounting这两个派生类,但是我们却可以调用classmate的eat和drink方法,而且我们在occupation中也可以使用父类的name属性。magic!代码在下面~

       二、多继承

      现在我们基本可以使用类的继承描述同坐一桌的同学们了,但是我们现在又有了一个新需求,就是把这一桌的男生和女生分开,男生喝酒,女生喝饮料,这个需求怎么用类来区别呢?先上图~

          

                                 

      我们看上面左侧这张图,由于需求的增加,要求把同桌的男生和女生分开,我又新写了两个female和male类重新定义drink方法,并且又定义了新的类fe_pythoner和ma_pythoner,所以这两个类什么也不做,只是分别继承female、classmate和male、classmate类。在实例化对象的时候我们使用fe_pythoner和ma_pythoner,我们这样猜想,这个时候对象eva和sweet是不是应该分别去调用female和male中的drink方法呢?执行下,看看下面的结果。什么鬼?竟然还是输出了基类的drink方法。再看看右边,没错,我只是在定义基类的时候让基类继承了object,它就可以按照我们想要的方法输出了。

      三、经典类的深度优先和新式类的广度优先

      那么原理是什么呢?这个时候我就要盗一张图来解释这个问题了:

         

      我们看上面的图,先放两句概念上来吓唬吓唬你:

    • 当类是经典类时,多继承情况下,会按照深度优先方式查找
    • 当类是新式类时,多继承情况下,会按照广度优先方式查找

      那么什么是经典类和新式类呢?简而言之,继承自object的类就叫做新式类,object类是python提供的,现在我们还不需要管它从哪里来,因为让类中的很多操作变得更合理了,我们以后记着就这么写就对了。注:下面小伙伴提到,python3.X版本中的类继承默认就是广度优先。

      下面来说广度优先和深度优先,首先,B和C两个类都必须继承自D,A类又继承自B、C,就是针对这种情况,没有为什么。。。背下来!我们对应起来看,这里的基类D就是上例中的classmate,BC就是pythoner和female,A则对应fe_pythoner类。

      经典类中:当我们这样写:fe_pythoner(pythoner,female),对象调用方法的时候,会先在fe_pythoner里面找,然后依次去找pythoner、classmate、最后再找female。如果找到了,就会执行,并且不再继续找下去了。所以我们刚刚在左侧举出得栗子中它先找到了classmate中的drink方法,才打印出了同样的内容。这就是深度优先。

      新式类中:当我们这样写:fe_pythoner(pythoner,female),对象调用方法的时候,会先在fe_pythoner里面找,然后依次去找pythoner、female、最后再找classmate。如果找到了,就会执行,并且不再继续找下去了。所以我们刚刚在右侧举得栗子中它先找到了female、或male中的drink方法,就打印了不同的内容。这就是广度优先。

      如果上面那些你通通没搞清楚,也没关系,在继承的时候可以直接把female类写在前面 fe_pythoner(female,pythoner),这么一来不管怎么样,都是先找female了。

      参考:http://www.cnblogs.com/wupeiqi/p/4493506.html

     
     
  • 相关阅读:
    一个简单例子:贫血模型or领域模型
    eclipse从数据库逆向生成Hibernate实体类
    Hibernate unsaved-value 属性
    webservice和restful的区别
    Web Service 的工作原理
    Hibernate3的DetachedCriteria支持
    hibernate criteria中Restrictions的用法
    Google Gson 使用简介
    struts2 访问国际化资源 <s:text>作为属性
    EL表达式从request和session中取值
  • 原文地址:https://www.cnblogs.com/jinyudong/p/7818730.html
Copyright © 2011-2022 走看看