Beng Dou

一只站在树上的鸟儿,从来不会害怕树枝断裂,因为它相信的不是树枝,而是它自己的翅膀。

导航

[ Python入门教程 ] Python面向对象编程(下)

  本文主要通过几个实例介绍Python面向对象编程中的封装、继承、多态三大特性。

封装性

  我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性。代码如下:

#-*- coding:utf-8 -*-

#类的创建
class Student(object):
    
    def __init__(self, name, age): 
        self.name = name  
        self.age = age 
           
if __name__ == '__main__':
    stu1 = Student('Zhangsan', 18)
    stu1.age = -1
    print stu1.age

  实例中将Stu1对象的age属性值成功修改为-1,这在程序中没有问题。但在现实生活中是不合理的。因此,在进行Student类设计时,需要对age、name属性做一些访问限定,不允许外界随便访问。这就需要实现类的封装。

  所谓类的封装是指在定义一个类时,将类中的属性私有化,私有属性只能再它所在类中被访问。为了能让外界访问私有属性,可以设置公共接口去获取或者修改属性值。我们通过修改代码,实现Student类的封装。修改后代码如下:

#-*- coding:utf-8 -*-

#类的创建
class Student(object):
    
    def __init__(self): 
        self.__name = ""  
        self.__age = 0
        
    def setName(self, name):
        self.__name = name 
        
    def setAge(self, age):
        if (age > 0):
            self.__age = age
        else:
            print "input age invalid"
        
    def getName(self):
        return self.__name
        
    def getAge(self):
        return self.__age        
if __name__ == '__main__':
    stu1 = Student()
    stu1.setName("Zhangsan")
    stu1.setAge(-1)
    print "stu1.getName() = %s" % (stu1.getName(),)
    print "stu1.getAge() = %d" % (stu1.getAge(),)

   代码说明:

(1)name、age定义有实例私有属性。Python没有类似Java中的private、procoted、public的修饰符去区分实例私有属性和实例公有属性。而是通过在属性的名字前以是否存在两个下划线开始为标志,如果存在双下划綫就表示为私有属性。反之,则表示公有属性。

(2)setName()、setAge()方法用于设置属性的值,可以在函数里增加逻辑对输入的参数进行判断。getName()、getAge()方法作为外部接口,用于获取属性的值。实现了对属性操作的封装。

继承性

  继承是面向对象的重要特性之一。通过继承可以创建新类,目的是使用或修改现有类的行为。原始的类称为父类或超类,新类称为子类或派生类。继承可以实现代码的重用。Python在类名后使用一对括号表示继承的关系,括号中的类即为父类。如果父类定义了__init__方法,子类必须显示调用父类的__init__方法。如果子类需要扩展父类的行为,可以添加__init__方法的参数。下面这段代码演示了继承的实现。

#-*- coding:utf-8 -*-

#类的创建
class Fruit(object):
    def __init__(self, color):  #__init__为类的构造函数
        self.color = color  #实例属性
        print "Fruit's color = %s " % (self.color,)
    
    def grow(self):
        print "Fruit grow()"

class Apple(Fruit):   #继承自Fruit类
    def __init__(self, color, name):  #子类的构造函数
        Fruit.__init__(self, color)  #显式调用父类的构造函数
        print "Apple's color = %s " % (self.color,) 
        self.name = name  #新增属性
    
    def sale(self):
        print "Apple sale()" # 改写父类中的grow方法

class Banana(Fruit):   #继承自Fruit类
    def __init__(self, color):  #子类的构造函数
        Fruit.__init__(self, color)  #显式调用父类的构造函数
    
    def grow(self): #新增方法
        print "Banana grow()"
        
if __name__ == '__main__':
    apple = Apple('red', 'apple') #
    apple.grow()  #继承父类的grow方法,可以直接调用
    apple.sale()
    banana = Banana('yellow')
    banana.grow() #

  例子中Apple类通过继承Fruit类,自动拥有了color属性和grow()方法。通过继承的方式,可以减少代码的重复编写。

多态性

  继承机制说明子类具有父类的公有属性和方法,而且子类可以扩展自身的功能,添加新的属性和方法。因此,子类可以替代父类对象,这种特性称为多态性。由于Python的动态类型,决定了Python的多态性。下面看吧这一段代码。

#-*- coding:utf-8 -*-

#类的创建
class Fruit(object):
    def __init__(self, color=None):  #__init__为类的构造函数
        self.color = color  #实例属性
 
class Apple(Fruit):   #继承自Fruit类
    def __init__(self, color='red'):  #子类的构造函数
        Fruit.__init__(self, color)  #显式调用父类的构造函数

class Banana(Fruit):   #继承自Fruit类
    def __init__(self, color='yellow'):  #子类的构造函数
        Fruit.__init__(self, color)  #显式调用父类的构造函数
    
class Fruitshop(object):
    def sellFruit(self, fruit):
        if isinstance(fruit, Apple):
            print "sell apple"
        if isinstance(fruit, Banana):
            print "sell apple"
        if isinstance(fruit, Fruit):
            print "sell Fruit"            
if __name__ == '__main__':
    shop = Fruitshop()
    apple = Apple()
    banana = Banana()
    shop.sellFruit(apple)
    shop.sellFruit(banana)

输出结果如下:

sell apple
sell Fruit
sell apple
sell Fruit

  在Fruitshop类中定义了sellFruit()方法,该方法提供参数fruit。sellFruit()根据不同的水果类型返回不同的结果。实现了一种调用方式不同的执行结果。这就是多态。利用多态性,可以增加程序的灵活性和可扩展性。

posted on 2018-06-17 08:06  锅边糊  阅读(595)  评论(0编辑  收藏  举报