python - 面向对象(二)

类的三大特性
类的三大特性包括:
封装、继承、多态

一、封装

封装就是将类所用到的所有字段、属性、方法都包含在类代码段里面,当实例调用直接调用类中的方法即可。

class People(object):

    def __init__(self,name):
        self.name = name

    def talk(self):
        print('my name is {0}'.format(self.name))

将函数talk() 封装到了类People下面,当实例化调用此函数时,只需要实例名+方法名即可调用

zhangsan = People('zhangsan')
zhangsan.talk(

out:

my name is zhangsan

对于类中的一些方法,如果我们在初始化(构造函数)中需要调用时,可以写成私有方法。这样在实例化对象后就直接执行。

class People(object):
    color = 'red'

    def __init__(self,name):
        self.name = name
        self.__talk()

    def __talk(self):
        print('my name is {0},color is {1}'.format(self.name,self.color))

zhangsan = People('zhangsan')

out:

my name is zhangsan,color is red

不用再调用talk()方法了

 

二、继承

继承是子类可以拥有父类的方法及属性、字段(对象字段), 但不可以继承类的私有方法(__开头的方法).
对于父类中有的方法,子类可以直接使用也可以重写。

 

class People(object):
    color = 'red'

    def __init__(self, name):
        self.name = name
        self.__talk()

    def __talk(self):
        print("my name is {0}, color is {1}".format(self.name, self.color))
    def show_job(self):
        print(" No job")

class Teacher(People):
    def __init__(self, name, age):
        super(Teacher, self).__init__(name)
        self.age = age
        self.__talk()

    def __talk(self):
        print("I'm Tearcher,  I'm {0}".format(self.age))
    def show_job(self):
        print(" Teacher")

zhangsan = Teacher("zhangsan",20)
zhangsan.show_job()

out:

my name is zhangsan, color is red
I'm Tearcher,  I'm 20
 Teacher

如上,虽然People与Teacher均有__talk方法,但该方法为私有方法,子类Teacher是无法继承的,而且show_job方法 虽然父类People中也有,但子类进行了重写。这样实例化调用时,仍然调动子类方法。

 

继承顺序:

经典类: 深度优先
新式类: 广度优先
在python2.x中对于多继承存在一个bug,对于新式类和经典类的多继承有以上区分,在python3.x中已经修复了,均为广度优先。

经典类:

class Father():
    def show(self):
        print("show in Father")

class Son_1(Father):
    def __init__(self):
        pass

class Son_2(Father):
    def show(self):
        print("show in Son_2")

class subSon(Son_1,Son_2):
    def __init__(self):
        pass

p = subSon()
p.show()

out:

show in Son_2

新式类:

class Father(object):
    def show(self):
        print("show in Father")

class Son_1(Father):
    def __init__(self):
        pass

class Son_2(Father):
    def show(self):
        print("show in Son_2")

class subSon(Son_1,Son_2):
    def __init__(self):
        pass

p = subSon()
p.show()

out:

show in Son_2

 

以上结果是在python3中执行的结果

python3 中 经典类和新式类 都是以广度优先

广度优先:先去Son_1中找,如果找不到就去兄弟节点Son_2中找,都没有就去父类Father中找。

如果子类的两个父类没有共同的父类的话,是一条道走到黑,即深度优先
如果子类的两个父类有共同的父类的话,是Son_1   然后是Son_2-->Father  ,即 广度优先

更多继承的详细讲解,请参考我的另外一篇博客  http://www.cnblogs.com/pangguoping/p/5699630.html

 

三、多态

什么是多态,简而言之就是对于同一个方法或函数,根据不同的输入能获取不同的结果的表现形式,多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为”一个接口,多个功能”。

python是一门弱类型语言,对于所有函数或类方法只有在调用时才知道数据的类型。它是不支持多态的,也不需要使用多态。

Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚“鸭子类型”。

 

class F1:
    pass


class S1(F1):

    def show(self):
        print 'S1.show'


class S2(F1):

    def show(self):
        print 'S2.show'


# 由于在Java或C#中定义函数参数时,必须指定参数的类型
# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类
# 而实际传入的参数是:S1对象和S2对象

def Func(F1 obj):
    """Func函数需要接收一个F1类型或者F1子类的类型"""
    
    print obj.show()
    
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show

s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
Python伪代码实现Java或C#的多态

 

class F1:
    pass


class S1(F1):

    def show(self):
        print 'S1.show'


class S2(F1):

    def show(self):
        print 'S2.show'

def Func(obj):
    print obj.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj) 
Python “鸭子类型”

 

 

参考:

http://blog.csdn.net/songfreeman/article/details/50815701

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

posted @ 2016-07-26 07:32  unixfbi.com  阅读(227)  评论(0编辑  收藏  举报