《Python编程的术与道:Python语言入门》视频课程
《Python编程的术与道:Python语言入门》视频课程链接:https://edu.csdn.net/course/detail/27845
当想扩展现有类的功能时,只需修改这个类。 但是,这样做很有可能会使它变得更复杂,或者破坏以前有用的功能。
当然,你可以编写一个新类。 但这意味着需要维护更多的代码。
解决方案是继承。
继承是从现有的类创建新类的过程。
通过继承创建的类可以使用旧类中的所有代码(例如属性和方法)。
因此,仅编辑需要在新类中进行修改的内容,这会重写(覆盖,override)旧类的行为。
当一个类从另一个类继承时,该继承类称为子类(subclass)、 或派生类(derived class),而从其继承的类称为其父类(parent class)、超类(superclass)或基类(base class)。
类之间存在层次关系。 这类似于从现实生活中了解的关系。
考虑一下车辆:自行车、汽车、公共汽车和卡车都具有车辆的特征(速度、颜色、档位)。 但是,每种都有其他功能,使它们与众不同。
可以在Python中实现Vehicle作为基类。 而汽车、公共汽车、卡车和自行车可以作为继承自车辆的子类来实现。
任何不从另一个类继承的类都称为基类。
下面的示例定义了一个称为Vehicle的基类。 它具有一种称为description的方法,可打印车辆的描述。
示例:定义一个称为Vehicle的基类
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
在现有类的基础上增加新类的行为称为子类化。 它允许添加新功能或覆盖现有功能。
现在,我们创建一个名为Car的Vehicle的子类。
可以使用相同的class关键字创建一个子类,但基类名称应放在括号内。
示例:创建名为“Car”的“Vehicle”的子类
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
# subclass
class Car(Vehicle):
pass
现在让我们从每个类中创建一个对象,然后调用description方法:
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
# subclass
class Car(Vehicle):
pass
# create an object from each class
v = Vehicle()
c = Car()
v.description() # I'm a Vehicle!
c.description() # I'm a Vehicle!
I'm a Vehicle!
I'm a Vehicle!
注意,不需要做任何特殊的事情,新的Car类就自动获得了Vehicle的所有特征,例如description()方法。
如你所见,Car类继承了其基类Vehicle的所有内容。
但是,子类应该在某种程度上不同于其基类。 否则,定义新类是没有意义的。
让我们重新定义Car内部的description()方法:
示例:重写description()方法
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
# subclass
class Car(Vehicle):
def description(self):
print("I'm a Car!")
# create an object from each class
v = Vehicle()
c = Car()
v.description() # I'm a Vehicle!
c.description() # I'm a Car!
I'm a Vehicle!
I'm a Car!
在这里,当调用description()方法时,将调用该方法的Car子类版本。
这是因为当在子类中添加与基类同名的方法时,该方法将被重写(覆盖)。
当子类提供其自己的基类已经提供的方法的自定义实现时,称为重写(覆盖,overriding)。
不仅可以重写实例方法,还可以重写任何方法,包括__init __()
。
子类还可以添加其基类中不存在的方法。
让我们为Car类定义新的方法setSpeed()。
示例:为Car类添加新方法setSpeed()
# a parent class
class Vehicle():
def description(self):
print("I'm a", self.color, "Vehicle")
# subclass
class Car(Vehicle):
def description(self):
print("I'm a", self.color, self.style)
def setSpeed(self, speed):
print("Now traveling at", speed,"miles per hour")
# create an object from each class
v = Vehicle()
c = Car()
c.setSpeed(25) # Now traveling at 25 miles per hour
v.setSpeed(25) # AttributeError: 'Vehicle' object has no attribute 'setSpeed'
Now traveling at 25 miles per hour
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in
17
18 c.setSpeed(25) # Now traveling at 25 miles per hour
---> 19 v.setSpeed(25) # AttributeError: 'Vehicle' object has no attribute 'setSpeed'
AttributeError: 'Vehicle' object has no attribute 'setSpeed'
Car对象可以对setSpeed()方法调用作出反应,而Vehicle对象则不能。
重写方法时,有时想重用基类的方法并添加一些新内容。可以通过使用super()
函数来实现。
为了说明这一点,让我们重新定义Vehicle和Car类,但这一次使用__init __()
方法。
请注意,Vehicle类中的__init __()
调用仅具有“ color”参数,而Car类具有附加的“ style”参数。
# base class
class Vehicle():
def __init__(self, color):
self.color = color
def description(self):
print("I'm a", self.color, "Vehicle")
# subclass
class Car(Vehicle):
def __init__(self, color, style):
super().__init__(color) # invoke Vehicle’s __init__() method
self.style = style
def description(self):
print("I'm a", self.color, self.style)
# create an object from each class
v = Vehicle('Red')
c = Car('Black', 'SUV')
v.description() # I'm a Red Vehicle
c.description() # I'm a Black SUV
I'm a Red Vehicle
I'm a Black SUV
在这里,super()
调用超类的__init __()
方法。 因此,子类可以同时访问颜色和样式属性。
我们可以将新类定义如下:
class Car(Vehicle):
def __init__(self, color, style):
self.color = color
self.style = style
def description(self):
print("I'm a", self.color, self.style)
但这会破坏代码重用的目的。 我们使用super()来确保汽车可以完成vehicle可以做的所有事情,以及其他更多功能。
还有另一个好处; 如果将来Vehicle的定义发生更改,则super()将确保所有更改都会得到反映。
Python还支持多重继承,其中子类可以从多个超类继承。
在多重继承中,所有超类的特征都被继承到子类中。
让我们定义一个FlyingCar子类,该子类继承自GroundVehicle类和FlyingVehicle类。
# base class 1
class GroundVehicle():
def drive(self):
print("Drive me on the road!")
# base class 2
class FlyingVehicle():
def fly(self):
print("Fly me to the sky!")
# subclass
class FlyingCar(GroundVehicle, FlyingVehicle):
pass
# create an object of a subclass
fc = FlyingCar()
fc.drive() # Drive me on the road!
fc.fly() # Fly me to the sky!
Drive me on the road!
Fly me to the sky!
请注意,子类中有效地使用了两个超类的方法。