本文主要通过几个实例介绍Python面向对象编程中的封装、继承、多态三大特性。
封装性
我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性。代码如下:
#-*- coding:utf-8 -*-
#类的创建
classStudent(object):def __init__(self, name, age):
self.name=name
self.age=ageif __name__ == '__main__':
stu1= Student('Zhangsan', 18)
stu1.age= -1
print stu1.age
实例中将Stu1对象的age属性值成功修改为-1,这在程序中没有问题。但在现实生活中是不合理的。因此,在进行Student类设计时,需要对age、name属性做一些访问限定,不允许外界随便访问。这就需要实现类的封装。
所谓类的封装是指在定义一个类时,将类中的属性私有化,私有属性只能再它所在类中被访问。为了能让外界访问私有属性,可以设置公共接口去获取或者修改属性值。我们通过修改代码,实现Student类的封装。修改后代码如下:
#-*- coding:utf-8 -*-
#类的创建
classStudent(object):def __init__(self):
self.__name = ""self.__age =0defsetName(self, name):
self.__name =namedefsetAge(self, age):if (age >0):
self.__age =ageelse:print "input age invalid"
defgetName(self):return self.__name
defgetAge(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 -*-
#类的创建
classFruit(object):def __init__(self, color): #__init__为类的构造函数
self.color = color #实例属性
print "Fruit's color = %s" %(self.color,)defgrow(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 #新增属性
defsale(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 -*-
#类的创建
classFruit(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) #显式调用父类的构造函数
classFruitshop(object):defsellFruit(self, fruit):ifisinstance(fruit, Apple):print "sell apple"
ifisinstance(fruit, Banana):print "sell apple"
ifisinstance(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()根据不同的水果类型返回不同的结果。实现了一种调用方式不同的执行结果。这就是多态。利用多态性,可以增加程序的灵活性和可扩展性。