zoukankan      html  css  js  c++  java
  • 面向对象的三大特性介绍

    面向对象编程三大特性介绍

    上一节中我们讲了面向对象的一些基础知识,这一节我们继续加深 面向对象编程的知识,让大家更深层次的了解面向对象编程

    首先讲讲面向对象的三大特性:

    封装、继承、多态
    

    一、封装:

    封装:将内容封装到某个地方,之后调用的时候直接调用被封装在某处的内容

    1、将内容封装到某处:

    class People:                        #定义一个People类
        def __init__(self,name,age,sex): #构造方法,
                                        (当实例化对象时,自动执行这个方法)
            self.name = name
            self.age = age
            self.sex = sex
    
    P1 = People('allen','25','male') #实例化对象P1,将"allen"、25、"male"分别封装 
                                      到了 P1/self 中的name,age,sex属性中 
    P2 = People('yyh','18','male')   #P2 ,同上
        
    
    # __init__ 中的self是一个形式参数,在实例化对象P1和P2的过程中,self分别等于P1和P2, 相对于内容被分别封装到了P1和P2中,每个对象都有name、age、sex属性。
    
    

    2、从某处调用被封装的内容:

    通过对象直接调用被封装的内容

    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    P1 = People('allen','25','male')
    P2 = People('yyh','18','male')
    
    print P1.name       #直接调用P1对象的name属性
    print P2.name       #直接调用P2对象的name属性
    

    执行结果如下

    allen    
    yyh
    
    

    通过self间接调用被封装的内容

    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def getInfo(self):
            print self.name   
            print self.age
            print self.sex
    
    P1 = People('allen','25','male')  
    P2 = People('yyh','18','male')
    
    P1.getInfo()  #python默认会将P1传给self参数,即P1.getInfo(P1),此时P1=self,
    P1.name等于self.name 是allen;self.age 是25;self.name 是male
    P2.getInfo() #同上
    

    二、继承:

    继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

    class Fruit:
        def __init__(self,color):
            self.color = color
            print "fruit's color: %s" %self.color
    
        def grow(self):
            print "This is grow ..."
    
    class Apple(Fruit):                             #继承了父类
        def __init__(self, color):                  #显示调用父类的__init__方法
            Fruit.__init__(self, color)
            print "apple's color: %s" % self.color
    
    class Banana(Fruit):                           #继承了父类
        def __init__(self,color):                  #显示调用父类的__init__方法
            Fruit.__init__(self,color)
            print "banana's color:%s" % self.color
    
        def grow(self):                            #覆盖了父类的grow方法
            print "banana grow..."
    
    apple = Apple('red')
    apple.grow()
    banana = Banana('yellow')
    banana.grow()
    

    执行结果如下:

    fruit's color: red
    apple's color: red
    This is grow ...
    fruit's color: yellow
    banana's color:yellow
    banana grow...                                #覆盖了父类的grow 方法
    
    对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而
    不必一一实现每个方法。
    

    那么问题来了,多继承如何做?

    是否可以继承多个类?

    如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?

    对于多继承中,就要区分经典类和新式类,我上面写的例子都是经典类的写法,
    对于新式类,要在类名后的括号中写上object,即class className(object),
    object 也是一个类,class className(object),相对于继承了object 类,
    则这个类称为新式类,新式类是我们今后推荐的写法
    
    当类是经典类时,多继承情况下,会按照深度优先方式查找
    当类是新式类时,多继承情况下,会按照广度优先方式查找
    

    经典类多继承例子:

    class D:                  #经典类     
        def bar1(self):
            print "D.bar1"
    
    class C(D):
        def bar1(self):
            print "C.bar1"
    
    class B(D):
        # def bar1(self):
        #     print "B.bar1"
        pass                  #pass 代表什么也不做
    
    class A(B,C):
        # def bar1(self):
        #     print "A.bar1"
        pass                  #pass 代表什么也不做
    
    op = A()                  #实例化对象op
    op.bar1()                 #访问op中bar1方法,但是具体访问到哪个方法呢???
    

    执行结果如下:

    D.bar1   #为什么是访问到了D.bar1 ? ,
    

    分析如下:

    当我们实例化op,并且调用bar1方法时,由于在类中有多个bar1方法,因此对于经典类,它自己
    有一个查找顺序,A ---> B --> D --> C, 什么意思呢?
    
    我们分析一下:
    首先找A,如果A中没有,则找B,如果B中没有,再找D,如果D中也没有,最后找C,都没有找到
    则报错;这种访问方式叫做深度优先
    
    对于我们上面这个例子,由于找A 和 B 时都没有找到,则找到了D,因此打印了D.bar1,
    

    新式类多继承例子

    class D(object):          #新式类    
        def bar1(self):
            print "D.bar1"
    
    class C(D):
        def bar1(self):
            print "C.bar1"
    
    class B(D):
        # def bar1(self):
        #     print "B.bar1"
        pass                  #pass 代表什么也不做
    
    class A(B,C):
        # def bar1(self):
        #     print "A.bar1"
        pass                  #pass 代表什么也不做
    
    op = A()                  #实例化对象op
    op.bar1()                 #访问op中bar1方法,但是具体访问到哪个方法呢???
    

    执行结果如下

    C.bar1                   #为什么是C.bar1 ?? 和经典类结果相差很大...为什么? 
    

    分析如下:

    新式类追寻的规律如下:
    A --> B --> C --> D
    意思是,首先找A,如果A中没有,则找B,如果B中没有,则找C,如果C中也没有,则找D,最后
    都没找到,则报错;这种访问方式叫广度优先
    
    对于我们上面的例子,由于A ,B 中都没有,则找C,C中找到了则打印C.bar1,
    对于广度优先,你可以理解为找最近的点,比如上面的例子,A继承B,C ,由于在B中找不到,则
    去找C,(因为A继承C,离A最近,)找到C,则直接打印C.bar1
    

    三、多态

    Pyhon不支持多态并且也用不到多态,这里简单带过,不做过多介绍

    首先python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。
    
    以下是维基百科中对鸭子类型得论述:
    
    在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,
    一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的
    集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”
    可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只
    鸟就可以被称为鸭子。”
    这里不做过多介绍
    

    今晚就写到这里,之后的篇章中还会陆续介绍面向对象相关的内容

    更多链接:http://www.cnblogs.com/wupeiqi/p/4493506.html

  • 相关阅读:
    重置mysql数据库密码
    windows下IIS+PHP解决大文件上传500错问题
    ecmobile中IOS版本中界面文字不显示的解决
    linux下重置mysql的root密码
    nginx下rewrite参数超过9个的解决方法
    android模拟器停在Waiting for HOME解决方案
    android模拟器没法通过localhost访问本地服务器的解决
    zend studio导入svn项目后不能代码提示的解决
    排序(1)

  • 原文地址:https://www.cnblogs.com/yangyinghua/p/5024892.html
Copyright © 2011-2022 走看看