面向对象的三大特性介绍

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

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

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

封装、继承、多态

一、封装:

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

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

posted @ 2015-12-07 01:07  杨英华Allen(夏佐)  阅读(2499)  评论(3编辑  收藏  举报