继承和多态
•继承是面向对象的重要特性之一,可实现代码的重用。
•通过继承可以创建新类,给既有类的副本添加变量和方法。
•原始的类称为父类或超类,新类称为子类或派生类。
•继承可以重用已经存在的数据和行为,减少代码的重复编写。
•Python在类名后使用一对括号表示继承关系,括号中即为父类。
关于在单继承关系中的构造函数:
•python中如果子类有自己的构造函数,不会自动调用父类的构造函数,如果需要用到父类的构造函数,则需要在子类的构造函数中显式地调用。如果子类需要扩展父类的行为,可以添加__init__方法的参数。
•如果子类没有自己的构造函数,则会直接从父类继承构造函数。
1、使用继承
•当类设计完成之后,就可以考虑类之间的逻辑关系。类之间存在继承、组合、依赖等关系,可以采用UML工具表示类之间的关系。
•例如,有两个子类Apple、Banana继承自父类Fruit,父类中有1个公有实例变量和1个公有的方法。下图表示了Fruit类和Apple、Banana类之间的继承关系(公有实例变量和方法假定用“+”表示)。
•Apple、Banana类可以继承Fruit类的实例变量color和方法grow()。
#类的继承
class Fruit(object): #基类
def __init__(self,color):
self.color=color
print('fruit’s color: %s' %self.color)
def grow(self):
print('grow...')
class Apple(Fruit): #继承Fruit类
def __init__(self,color): #子类的构造函数
Fruit.__init__(self,color) #显式的调用基类的构造函数
print("apple's color: %s " % self.color)
class Banana(Fruit):
def __init__(self,color): #子类的构造函数
Fruit.__init__(self,color) #显式的调用基类的构造函数
print("banana's color: %s " % self.color)
def grow(self):
print('banana grow...')
if __name__=="__main__":
apple=Apple('red')
apple.grow()
banana=Banana('yellow')
banana.grow()
输出结果:
fruit’s color: red
apple's color: red
grow...
fruit’s color: yellow
banana's color: yellow
banana grow...
多态的应用实例
#多态性应用(一个简单的游戏)
import random
class Player(object): #基类
def __init__(self,name):
self._name=name
self._score=0
def reset_score(self):
self._score=0
def incr_score(self):
self._score+=1
def get_name(self):
return self._name
def __str__(self):
return "name='%s',score=%d" % (self._name,self._score)
def __repr__(self):
return 'Player(%s)' % str(self)
class Computer(Player): #player 的派生类
def __repr__(self):
return 'Computer(%s)' %str(self)
def get_move(self):
return random.randint(1,10)
class Human(Player):
def __repr__(self):
return 'Human(%s)' % str(self)
def get_move(self):
while True:
n=int(input('%s move(1-10):' % self.get_name()))
if 1<=n<=10:
return n
else:
print('Oops!')
def play_undercut(p1,p2):
p1.reset_score()
p2.reset_score()
m1=p1.get_move()
m2=p2.get_move()
print('%s move %d' %(p1.get_name(),m1))
print('%s move %d' %(p2.get_name(),m2))
if m1==m2-1:
p1.incr_score()
return p1,p2, '%s win' % p1.get_name()
elif m2==m1-1:
p2.incr_score()
return p1,p2, '%s win' % p2.get_name()
else:
return p1,p2, 'draw no winner'
h1=Human('Jack')
h2=Human('Bob')
print(play_undercut(h1,h2))
输出结果:
Jack move(1-10):6
Bob move(1-10):4
Jack move 6
Bob move 4
(Human(name='Jack',score=0), Human(name='Bob',score=0), 'draw no winner')