继承(Inheritance)是面向对象软件技术当中的一个概念。如果一个类
别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为A
的父类别,也可以称B是A的超类。
从逻辑上说,继承的目的也不是为了复用代码,而是为了理顺关系。
对于python中的继承,前面一直在使用,那就是我们写的类都是新式类,
所有新式类都是继承自object类。新式类的一种写法:
class NewStyle(object):
pass
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
注意,没有定义初始化函数,初始化函数在类汇总不是必不可少的。
class Person:#首先定义了一个类Person,在这个类中定义了三个方法。
def speak(self):
print "I love you."
def setHeight(self):
print "The height is: 1.60m ."
def breast(self, n):
print "My breast is: ",n
又定义了一个类Girl,这个类的名字后面的括号中,是上一个类的名字,
这就意味着Girl继承了Person,Girl是Person的子类,Person是Girl的父
类。
class Girl(Person):
def setHeight(self):
print "The height is:1.70m ."
if __name__ == "__main__":
cang = Girl()
cang.setHeight()
cang.speak()
cang.breast(90)
The height is:1.70m .
I love you.
My breast is: 90
如果Girl里面有一个和Person同样名称的方法,那么就把Person中的同一
个方法遮盖住了,显示的是Girl中的方法,这叫做方法的重写。
多重继承
所谓多重继承,就是只某一个类的父类,不止一个,而是多个。
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def eye(self):
print "two eyes"
def breast(self, n):
print "The breast is: ",n
class Girl:
age = 28
def color(self):
print "The girl is white"
class HotGirl(Person, Girl):
pass
if __name__ == "__main__":
kong = HotGirl()
kong.eye()
kong.breast(90)
kong.color()
print kong.age
打印:
two eyes
The breast is: 90
The girl is white
28
前面有两个类:Person和Firl,然后第三个类HotGirl继承了这两个类,
多重继承的顺序
#!/usr/bin/env python
# coding=utf-8
class K1(object):
def foo(self):
print "K1-foo"
class K2(object):
def foo(self):
print "K2-foo"
def bar(self):
print "K2-bar"
class J1(K1, K2):
pass
class J2(K1, K2):
def bar(self):
print "J2-bar"
class C(J1, J2):
pass
if __name__ == "__main__":
print C.__mro__
m = C()
m.foo()
m.bar()
打印:
(<class '__main__.C'>, <class '__main__.J1'>, <class
'__main__.J2'>, <class '__main__.K1'>, <class '__main__.K2'>,
<type 'object'>)
K1-foo
J2-bar
这种对继承属性和方法搜索的顺序称之为“广度优先”。
super函数
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def __init__(self):
self.height = 160
def about(self, name):
print "{} is about {}".format(name, self.height)
class Girl(Person):
def __init__(self):
self.breast = 90
def about(self, name):
print "{} is a hot girl, she is about {}, and her breast
is {}".format(name, self.height, self.breast)
if __name__ == "__main__":
cang = Girl()
cang.about("canglaoshi")
重要的是看报错信息。就是我们要打印的那句话出问题了,报错信息显示
self.height是不存在的。也就是说类Girl没有从Person中继承过来这个
属性。
解决方案
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def __init__(self):
self.height = 160
def about(self, name):
print "{} is about {}".format(name, self.height)
class Girl(Person):
def __init__(self):
super(Girl, self).__init__()
self.breast = 90
def about(self, name):
print "{} is a hot girl, she is about {}, and her breast
is {}".format(name, self.height, self.breast)
super(Girl, self).about(name)
if __name__ == "__main__":
cang = Girl()
cang.about("canglaoshi")
执行结果:
$ python 20903.py
canglaoshi is a hot girl, she is about 160, and her breast is 90
canglaoshi is about 160
在子类中,_init_方法重写了,为了调用父类同方法,使用super
(Girl.self)._init_()的方式。super函数的参数,第一个是当前子类的
类名字,第二个是self,然后是点号,点号后面是所要调用的父类的方法
。同样在子类重写的about方法中,也可以调用父类的about方法。
别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为A
的父类别,也可以称B是A的超类。
从逻辑上说,继承的目的也不是为了复用代码,而是为了理顺关系。
对于python中的继承,前面一直在使用,那就是我们写的类都是新式类,
所有新式类都是继承自object类。新式类的一种写法:
class NewStyle(object):
pass
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
注意,没有定义初始化函数,初始化函数在类汇总不是必不可少的。
class Person:#首先定义了一个类Person,在这个类中定义了三个方法。
def speak(self):
print "I love you."
def setHeight(self):
print "The height is: 1.60m ."
def breast(self, n):
print "My breast is: ",n
又定义了一个类Girl,这个类的名字后面的括号中,是上一个类的名字,
这就意味着Girl继承了Person,Girl是Person的子类,Person是Girl的父
类。
class Girl(Person):
def setHeight(self):
print "The height is:1.70m ."
if __name__ == "__main__":
cang = Girl()
cang.setHeight()
cang.speak()
cang.breast(90)
The height is:1.70m .
I love you.
My breast is: 90
如果Girl里面有一个和Person同样名称的方法,那么就把Person中的同一
个方法遮盖住了,显示的是Girl中的方法,这叫做方法的重写。
多重继承
所谓多重继承,就是只某一个类的父类,不止一个,而是多个。
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def eye(self):
print "two eyes"
def breast(self, n):
print "The breast is: ",n
class Girl:
age = 28
def color(self):
print "The girl is white"
class HotGirl(Person, Girl):
pass
if __name__ == "__main__":
kong = HotGirl()
kong.eye()
kong.breast(90)
kong.color()
print kong.age
打印:
two eyes
The breast is: 90
The girl is white
28
前面有两个类:Person和Firl,然后第三个类HotGirl继承了这两个类,
多重继承的顺序
#!/usr/bin/env python
# coding=utf-8
class K1(object):
def foo(self):
print "K1-foo"
class K2(object):
def foo(self):
print "K2-foo"
def bar(self):
print "K2-bar"
class J1(K1, K2):
pass
class J2(K1, K2):
def bar(self):
print "J2-bar"
class C(J1, J2):
pass
if __name__ == "__main__":
print C.__mro__
m = C()
m.foo()
m.bar()
打印:
(<class '__main__.C'>, <class '__main__.J1'>, <class
'__main__.J2'>, <class '__main__.K1'>, <class '__main__.K2'>,
<type 'object'>)
K1-foo
J2-bar
这种对继承属性和方法搜索的顺序称之为“广度优先”。
super函数
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def __init__(self):
self.height = 160
def about(self, name):
print "{} is about {}".format(name, self.height)
class Girl(Person):
def __init__(self):
self.breast = 90
def about(self, name):
print "{} is a hot girl, she is about {}, and her breast
is {}".format(name, self.height, self.breast)
if __name__ == "__main__":
cang = Girl()
cang.about("canglaoshi")
重要的是看报错信息。就是我们要打印的那句话出问题了,报错信息显示
self.height是不存在的。也就是说类Girl没有从Person中继承过来这个
属性。
解决方案
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class Person:
def __init__(self):
self.height = 160
def about(self, name):
print "{} is about {}".format(name, self.height)
class Girl(Person):
def __init__(self):
super(Girl, self).__init__()
self.breast = 90
def about(self, name):
print "{} is a hot girl, she is about {}, and her breast
is {}".format(name, self.height, self.breast)
super(Girl, self).about(name)
if __name__ == "__main__":
cang = Girl()
cang.about("canglaoshi")
执行结果:
$ python 20903.py
canglaoshi is a hot girl, she is about 160, and her breast is 90
canglaoshi is about 160
在子类中,_init_方法重写了,为了调用父类同方法,使用super
(Girl.self)._init_()的方式。super函数的参数,第一个是当前子类的
类名字,第二个是self,然后是点号,点号后面是所要调用的父类的方法
。同样在子类重写的about方法中,也可以调用父类的about方法。