我们经常遇到不同的产品,它们有一个基本模型和一个高级模型,在基本模型的基础上增加了一些功能。面向对象的软件建模方法能够扩展现有类的能力来构建新的类,而不是从头开始构建。在 OOP 术语中,这种特性被称为继承,现有的类被称为基类或父类,而新的类被称为子类或子类。
当一个新的类与一个现有的类具有“是”的关系时,继承就出现了。
狗是一种动物。猫也是一种动物。因此,动物是基类,而狗和猫是继承类。
四边形有四条边。矩形是四边形,正方形也是四边形。四边形是基类(也称为父类),而矩形和正方形是继承的类——也称为子类。
子类从父类继承数据定义和方法。这有助于重用已有的功能。子类可以添加一些定义或者重新定义一个基类方法。
这个特性在为系统中的对象构建类的层次结构时非常有用。也可以基于一个以上的现有类设计一个新类。这个特性叫做多重继承。
建立继承的一般机制如下所示:
Syntax:
class parent:
statements
class child(parent):
statements
定义子类时,父类的名称放在它前面的括号中,表示两者之间的关系。父类中定义的实例属性和方法将被子类的对象继承。
为了演示一个更有意义的例子,首先定义一个四边形类,并将其用作矩形类的基类。
具有四条边作为实例变量和周长()方法的四边形类定义如下:
Example:
class quadriLateral:
def __init__(self, a, b, c, d):
self.side1=a
self.side2=b
self.side3=c
self.side4=d
def perimeter(self):
p=self.side1 + self.side2 + self.side3 + self.side4
print("perimeter=",p)
构造器(__init__()
方法)接收四个参数,并将它们分配给四个实例变量。要测试上述类,请声明其对象并调用perimeter()
方法。
>>>q1=quadriLateral(7,5,6,4)
>>>q1.perimeter()
perimeter=22
我们现在基于quadriLateral
类设计一个矩形类(矩形是四边形!).实例变量和基类中的perimeter()
方法应该自动对其可用,而无需重新定义。
由于矩形的相对边是相同的,我们只需要两个相邻的边来构造它的对象。因此,__init__()
方法的另外两个参数被设置为无。 方法使用 super() 函数将参数转发给其基(四边形)类的构造器。 对象初始化时将side3
和side4
设置为无。 矩形类的构造器使对边相等。请记住,它已经自动继承了perimeter()
方法,因此没有必要重新定义它。
Example: Inheritance
class rectangle(quadriLateral):
def __init__(self, a, b):
super().__init__(a, b, a, b)
我们现在可以声明矩形类的对象并调用perimeter()
方法。
>>> r1=rectangle(10, 20)
>>> r1.perimeter()
perimeter=60
在 Python 中重写
在上面的例子中,我们看到了如何在构造继承类时重用基类的资源。但是,继承的类可以有自己的实例属性和方法。
父类的方法可用于继承的类。但是,如果需要,我们可以修改任何基类方法的功能。为此,继承的类包含方法的新定义(与基类中已经存在的名称和签名相同)。很自然,一个新类的对象可以访问这两种方法,但是当被调用时,来自它自己的类的对象将具有优先权。这称为方法重写。
首先,我们将在矩形类中定义一个名为area()
的新方法,并将其用作square
类的基础。矩形的面积是其相邻边的乘积。
Example:
class rectangle(QuadriLateral):
def __init__(self, a,b):
super().__init__(a, b, a, b)
def area(self):
a = self.side1 * self.side2
print("area of rectangle=", a)
让我们定义继承矩形类的正方形类。area()
方法被覆盖,以实现将正方形面积作为其边的正方形的公式。
Example:
class square(rectangle):
def __init__(self, a):
super().__init__(a, a)
def area(self):
a=pow(self.side1, 2)
print('Area of Square: ', a)
>>>s=Square(10)
>>>s.area()
Area of Square: 100
```****