Python面向对象编程(下)
Posted Beng Dou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()根据不同的水果类型返回不同的结果。实现了一种调用方式不同的执行结果。这就是多态。利用多态性,可以增加程序的灵活性和可扩展性。
以上是关于Python面向对象编程(下)的主要内容,如果未能解决你的问题,请参考以下文章