面向对象编程OOP
有以下三个特征,本篇札记中主要讨论继承
的知识点:
继承
概念
继承inheritance
是面向对象设计中一个重要的概念。如果一个类A继承自另一个类B
,则称B
是A
的父类或者超类
,或者A是B的子类
。
继承可以使得子类具有父类的属性和方法,不再需要重新编写方法。同时,子类还可以重新定义自己的属性和方法,或者重新写某些方法,即覆盖掉父类的属性和方法。
继承特点
- 在
Python
中所有的类都是object
的子类,即所有的类都继承自object
。 - 子类继承父类的所有方法和属性
- 实现代码重用,子类还可以定义自身特有的属性和方法
- 继承最主要的功能是实现
多态
,多态的重要性是实现接口的继承性
在Python
中由于存在Duck Type
,接口定义的重要性被降低了,继承的作用也被大大降低。
单继承
单继承就是指只从一个父类那里继承,即只有一个父类。通过一个简单的例子来了解继承:
class A:
pass
class B(A):
pass
B.__base__
image.png
- A是父类,B是子类
- 所有的类都是object的子类,
object类不必写出来
;如果继承别的类,则必须写出来 __ base__
属性查看某个类的父类
通过一个例子来真正了解下继承:
import random
class A:
def __init__(self, number):
num = random.randint(1, 101)
if num > number:
print("{} is bigger than number".format(num))
else:
print("{} is smaller than number".format(num))
class B(A):
pass
res = B(50)
image.png
image.png
- 例子中父类
A
中增加了初始化函数__init__()
- 建立实例的时候执行初始化函数
B
继承了A
,也就拿到了初始化函数- 当建立
res = B(50)
实例的时候,执行了父类的初始化函数,就是继承
class Person:
def __init__(self,name):
self.name = name
def height(self,m):
h = dict((["height", m],))
return h
def color(self,n):
return dict((["color", n],))
def age(self,k):
return dict((["age", k],))
class Boy(Person):
def get_name(self):
return self.name
if __name__ == "__main__":
boy = Boy("xiaoming")
print(boy.get_name())
print(boy.height(180))
print(boy.color("yelloow"))
print(boy.age(25))
结果:
xiaoming
{'height': 180}
{'color': 'yelloow'}
{'age': 25}
class Person:
def __init__(self,name):
self.name = name
def height(self,m):
h = dict((["height", m],))
return h
def color(self,n):
return dict((["color", n],))
def age(self,k):
return dict((["age", k],))
class Boy(Person):
def __init__(self):
self.name = "Peter"
def get_name(self):
return self.name
if __name__ == "__main__":
boy = Boy("xiaoming")
print(boy.get_name())
print(boy.height(180))
print(boy.color("yelloow"))
print(boy.age(25))
运行结果报错:
- 创建实例的时候,传入的参数过多
- 子类中初始化函数只有一个
self
,和父类的初始化函数重名 - 子类继承了父类的初始化函数,导致
__init__()
方法同时传入两个参数 - 解决办法:实例化子类不再显示地传入参数。
image.png
- 通过上面的例子发现:如果子类中的方法或者属性和父类的重名,即覆盖了父类,则子类不再继承父类的该属性和方法,例如上面的
__init__()
方法。 - 子类和父类中同样名称的属性和方法,称之为子类对父类相应部分的
重写
。
调用覆盖的方法
上面的例子中子类重写了父类的某个方法,如果子类还是想使用父类的该方法,how to do it?
对子类进行如下的修改:
class Person:
def __init__(self,name):
self.name = name
def height(self,m):
h = dict((["height", m],))
return h
def color(self,n):
return dict((["color", n],))
def age(self,k):
return dict((["age", k],))
class Boy(Person):
def __init__(self, name):
Person.__init__(self, name)
self.real_name = "Peter"
def get_name(self):
return self.name
if __name__ == "__main__":
boy = Boy("xiaoming")
print(boy.real_name)
print(boy.get_name())
print(boy.height(180))
print(boy.color("yelloow"))
print(boy.age(25))