我们先说overload 重载。
在Java中,支持重载,重载的意思是能够定义有相同方法名的方法,传入方法中的参数个数,或者参数类型不同。比如:
int mymethod(int a, int b)
int mymethod(int num)
float mymethod(int a, float b)
float mymethod(float var1, int var2)
int mymethod(int a, int b)
int mymethod(float var1, float var2)
int mymethod(int a, int b, float c)
int mymethod(int var1, int var2, float var3)
def sum(a,b):
return a+b
def sum(a,b,c):
return a+b+c
print sum(1,2)
print sum(1,2,3)
# result
TypeError: sum() takes exactly 3 arguments (2 given)
所以,当我们想在python中运用类似overload的技巧的时候,更多的我们会使用
default argument values
def ask_ok(prompt, retries=4, complaint='Yes or no, please!')
你可以调用这个方法,传入不同个数的参数
ask_ok('Do you really want to quit?')
ask_ok('OK to overwrite the file?', 2)
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
keyword arguments
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
如果使用的keyword赋值,那么不需要按照顺序传入参数
parrot(1000) # 1 positional argument
parrot(voltage=1000) # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword
arbitrary argument lists
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
####################################################################################################################################
我们接着说python的override重写
在Java中,我们用extends 父类方法来继承,继承父类的方法,并可以重写方法中的内容。同时可以用super关键词调用父类的方法。
Python中可以做同样的事,没有extends,有super。
class Parent(object):
def myMethod(self):
print 'Calling parent method'
class Child(Parent):
def myMethod(self):
print 'Calling child method'
p = Parent()
p.myMethod()
c = Child()
c.myMethod()
# result
Calling parent method
Calling child method
但是继承了之后,可以使用super关键词来调用父类的方法
class Parent(object):
def myMethod(self):
print 'Calling parent method'
class Child(Parent):
def childMethod(self):
print 'Calling child method'
super(Child, self).myMethod()
p = Parent()
p.myMethod()
c = Child()
c.childMethod()
# result
Calling parent method
Calling child method
Calling parent method
####################################################################################################################################
扩展
1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。有别于C#
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
class BaseClass:
def __init__(self, name, age):
self.name = name
self.age = age
print "baseclass is inited"
def speak(self, name):
print "base class is speaking: %s" % name
class SubClass(BaseClass):
def __init__(self, name, age, salary):
BaseClass.__init__(self, name, age)# 调用父类函数要记得带上self,区别普通调用不需要self
self.salary=salary
print "SubClass is inited and the salary is: %s" % self.salary
def talk(self, sth):
print "%s talking: %s" % (self.name, sth)
BaseClass.speak(self, sth) # 调用父类函数要记得带上self,区别普通调用不需要self
if(__name__=="__main__"):
s=SubClass("Joan",1,800)
s.talk("a story")
# result
baseclass is inited
SubClass is inited and the salary is: 800
Joan talking: a story
base class is speaking: a story
假如子类中不用__init__初始化函数,那么子类会继承父类的属性
class BaseClass:
def __init__(self, name, age):
self.name = name
self.age = age
print "baseclass is inited"
def speak(self, name):
print "base class is speaking: %s" % name
class SubClass(BaseClass):
#def __init__(self, name, age, salary):
# BaseClass.__init__(self, name, age)
# self.salary=salary
# print "SubClass is inited and the salary is: %s" % self.salary
def talk(self, sth):
print "%s talking: %s, his age is %d" % (self.name, sth, self.age)
BaseClass.speak(self, sth)
if(__name__=="__main__"):
s=SubClass("Joan",1)# 初始化的时候,会先在本类中调用init方法,没有就调用父类的
s.talk("a story")
s.speak("directly use baseclass function") # 通过子类调用speak方法,会先在子类中查找,找到就直接调用,找不到就会寻找父类中调用
# result
baseclass is inited
Joan talking: a story, his age is 1
base class is speaking: a story
base class is speaking: directly use baseclass function
多重继承
class P1 #(object):
def foo(self):
print 'p1-foo'
class P2 #(object):
def foo(self):
print 'p2-foo'
def bar(self):
print 'p2-bar'
class C1 (P1,P2):
pass
class C2 (P1,P2):
def bar(self):
print 'C2-bar'
class D(C1,C2):
pass
d = D()
d.foo()
d.bar()
# result
p1-foo
p2-bar
当我们把object的注释取消掉之后,运行同样的代码
class P1 (object):
def foo(self):
print 'p1-foo'
class P2 (object):
def foo(self):
print 'p2-foo'
def bar(self):
print 'p2-bar'
class C1 (P1,P2):
pass
class C2 (P1,P2):
def bar(self):
print 'C2-bar'
class D(C1,C2):
pass
d = D()
d.foo()
d.bar()
print "MRO:", [x.__name__ for x in D.__mro__]
# result
p1-foo
C2-bar
MRO: ['D', 'C1', 'C2', 'P1', 'P2', 'object']
我们可以使用__mro__属性来查看查找顺序。
参考:
http://beginnersbook.com/2013/05/method-overloading/
http://forums.udacity.com/questions/20750/method-overloading-in-python
https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions
http://2577885.blog.51cto.com/2567885/669322
http://blog.csdn.net/seizef/article/details/5310107
http://www.cnblogs.com/Joans/archive/2012/11/09/2757368.html