在本教程中,您将掌握面向对象编程的基本概念,如继承、封装等,包括它们的语法和示例。此外,您还将了解OOP中不同类型的继承。
面向对象编程方法是最重要且被普遍接受的编程方法,因为它完全依赖于对象和类,这鼓励了模块化和软件可重用性。
面向对象编程的四个基本构建块是
本教程将详细介绍每种方法。所以,让我们开始学习继承。
继承可以定义为一个类在不修改现有类的情况下获取现有类特征(属性和方法)的过程。继承特征的类称为子类或派生类,从中继承特征的类称为父类或基类。换句话说,新形成的类是子类,而现有类称为父类。
例如,在现实世界中,父亲和母亲代表父类,而他们的孩子代表子类。孩子从父母那里获得了许多特征,同时,孩子也拥有父母可能没有的独特特征。用编程术语来说,我们可以说子类继承了父类的所有属性和方法,但同时子类也拥有自己独特的特性。
继承的语法如下
class Parent_class:
Body of parent_class
class Child_class(Parent_class):
Body of Child_class
在Python中,继承分为五种类型。它们是:
单继承是最简单、最容易的继承类型之一。在单继承中,子类继承父类的所有属性和方法。这使得代码可重用和模块化。
在这种情况下,A类是父类,B类是子类。B类有其自己独特的属性和方法,但仍然继承了A类的属性和方法。
单继承的语法如下:
class A:
pass
class B(A):
pass
观察此示例以查找矩形的面积。这里,Shape是父类,Rect是子类。在父类中,我们有一个函数display(),用于显示矩形的长度和宽度。在子类中,我们定义了函数area()来计算矩形的面积并打印输出。
class Shape: #Parent Class
def __init__(self,name,length,breadth):
self.name=name
self.l=length
self.b=breadth
def display(self):
print("Length is :",self.l)
print("Breadth is :",self.b)
class Rect(Shape): #Child Class
def area(self):
a=self.l*self.b
print("Area of",self.name,"is",a)
ob = Rect('Rectangle',10,20)
ob.display()
ob.area()
输出:
Length is : 10 Breadth is : 20 Area of Rectangle is 200
观察示例,您会注意到以下几点:
多级继承是一种继承类型,其中从派生类创建的类本身继承了一个基类。多级继承显示了从派生类或子类继承的可能性。因此,最简单的多级继承是三层结构,其中子类从派生类继承特性,而派生类又从超类继承属性。
在这里,A类是超类,B类是派生类,C类是子类。C类可以继承B类和A类的所有属性,而B类只能继承A类的特性。
语法如下 :
class A:
pass
class B(A):
pass
class C(B):
pass
让我们看看我们之前的示例是如何改变的。在这里,我们创建了一个名为Square的新类,它是Rect类的子类。
class Shape: #Superclass
def __init__(self,name,length,breadth):
self.name=name
self.l=length
self.b=breadth
def display(self):
print("Length is :",self.l)
print("Breadth is :",self.b)
class Rect(Shape): #Derived Class
def area(self):
a=self.l*self.b
print("Area of",self.name,"is",a)
class Square(Rect): #Child Class
def peri(self):
p =4*self.l
print("Perimeter of",self.name,"is",p)
obs = Square('Square',20,20)
obs.display()
obs.area()
obs.peri()
输出
Length is : 20 Breadth is : 20 Area of Square is 400 Perimeter of Square is 80
从示例中,您会注意到以下几点:
注意:子类可以访问超类,但反之则不然。
层次继承是一种继承类型,其中从基类创建了多个子类。
上图说明了层次结构,其中B类和C类继承了A类的属性,尽管它们都有自己独特的特性。
语法如下 :
class A:
pass
class B(A):
pass
class C(A):
pass
现在,让我们更改Shape类并看看层次继承是如何工作的。在这种情况下,我们有一个名为Shape的基类和两个子类,即Rect和Tri。两个类都从Shape类继承display()函数来打印长度和宽度。在Rect类中,我们计算矩形的面积;而在Tri类中,我们使用两个不同的函数R_area()和T_area()来计算三角形的面积。
class Shape:
def __init__(self,name,length,breadth):
self.name=name
self.l=length
self.b=breadth
def display(self):
print("Length is :",self.l)
print("Breadth is :",self.b)
class Rect(Shape):
def R_area(self):
a=self.l*self.b
print("Area of",self.name,"is",a)
class Tri(Shape):
def T_area(self):
a=0.5*self.l*self.b
print("Area of",self.name,"is",a)
obr = Rect('Rectangle',10,20)
obr.display()
obr.R_area()
obt = Tri('Triangle',10,20)
obt.display()
obt.T_area()
输出
Length is : 10 Breadth is : 20 Area of Rectangle is 200 Length is : 10 Breadth is : 20 Area of Triangle is 100.0
这里,由于我们使用了两个独立的子类,因此需要创建两个对象。obr是Rect类的对象,obt是Tri类的对象。使用obr,我们调用了base类Shape的特性函数display()。同样,对象obt调用函数display()。因此,这里两个不同的对象继承了它们基类的相同特性。除此之外,通过对象,两个类都调用了它们各自类Rect和Tri中定义的函数R_area()和T_area()。
当一个子类从两个基类创建时,它被称为多重继承。顾名思义,派生类继承了两个不同类的特性。
图示了C类对A类和B类属性的继承。在这里,A类和B类是C类的基类,C类可以获取这两个类的属性和方法。在现实生活中,孩子会继承父母双方的特征。
语法如下 :
class A:
pass
class B:
pass
class C(A , B):
pass
下面的示例展示了在Python中不使用super()的多重继承的工作方式。在这个例子中,我们有两个基类,即Mom类和Dad类,我们的子类是Kid。Kid类可以使用其对象obk从Mom类和Dad类继承特性,如示例所示。每个类都有独立的定义为feature_m、feature_d和feature_k的方法。
class Mom:
def feature_m(self):
print("Iam your mom")
class Dad:
def feature_d(self):
print("Iam your dad")
class Kid(Mom,Dad):
def feature_k(self):
print("Iam the Kid")
obk = Kid()
obk.feature_m()
obk.feature_d()
obk.feature_k()
输出
Iam your mom Iam your dad Iam the Kid
多重继承赋予了子类继承任意多个基类的自由。因此,在使用多重继承时,如果多个基类使用相同的名称来定义方法,会发生什么?让我们通过示例来理解。
class Mom:
def feature(self):
print("Iam your mom")
class Dad:
def feature(self):
print("Iam your dad")
class Kid(Mom,Dad):
def feature(self):
print("Iam the Kid")
obk = Kid()
obk.feature()
输出
Iam the Kid
这里我们对之前的示例做了一些小改动。所有方法都有相同的名称。我们收到的输出是“I am the kid”,它定义在子类Kid的feature方法中。为什么会这样?这是因为这里创建的是子类的对象,它总是首先调用自己的方法。
那么,我们应该如何访问其父类的特性呢?Python提供了一个名为super的关键字来解决这个问题。下面的程序将对此进行说明。
class Mom:
def feature(self):
print("I am your mom")
class Dad:
def feature(self):
print("I am your dad")
class Kid(Mom,Dad):
def feature(self):
super().feature()
print("I am the Kid")
obk = Kid()
obk.feature()
输出
I am your mom I am the Kid
程序中的一个小改动会带来新的结果。super().feature()调用了超类Mom中的方法。您是否想过它为什么没有调用它另一个超类Dad中的方法?接下来的部分将为您提供恰当的答案。
方法解析顺序(Method Resolution Order),在Python中通常称为MRO,是一套规则,用于搜索Python在类层次结构中查找方法的顺序。派生类被调用的顺序。方法被调用的顺序称为线性化。
MRO在处理多级继承场景时起着至关重要的作用,尤其是在处理多重继承时。原因在于,当层次结构中的多个类具有相同的方法时,Python首先在当前类中搜索给定的方法或属性,如果找不到,则以深度优先、从左到右的顺序搜索其父类。层次结构中的每个类都被搜索一次,直到到达其最终的基类,即object类。这意味着在Python中,任何用户定义类或内置类的基类都是object类。您将在下面的示例中清楚地了解。
Python提供了两种查看类MRO的方法:
class Mom:
def feature(self):
print("I am your mom")
class Dad:
def feature(self):
print("I am your dad")
class Kid(Mom,Dad):
def feature(self):
super().feature()
print("I am the Kid")
obk = Kid()
obk.feature()
print(Kid.mro())
print(Kid.__mro__)
输出
I am your mom I am the Kid [<class '__main__.Kid'>, <class '__main__.Mom'>, <class '__main__.Dad'>, <class 'object'>] (<class '__main__.Kid'>, <class '__main__.Mom'>, <class '__main__.Dad'>, <class 'object'>)
对于Kid类,MRO顺序是Kid ----> Mom ----> Dad ----> object class。
注意:MRO始终确保子类出现在其父类之前。
混合继承是Python中的一种继承,它结合了一种或多种继承形式,例如,多级继承与多重继承相结合。因此,它可以在超类和子类之间包含任意数量的中间类。随着层级的提高,复杂性也随之增加。
在这里,我们的混合结构中,D类是由两个派生类B和C创建的,它们的基类是A。这表明了多级继承和多重继承的结合。
观察下面的示例。
class Shape:
def __init__(self,name,length,breadth):
self.name=name
self.l=length
self.b=breadth
def display(self):
print("Length is :",self.l)
print("Breadth is :",self.b)
class Rect(Shape):
def R_area(self):
a=self.l*self.b
print("Area of",self.name,"is",a)
class Square(Shape):
def peri(self):
p =4*self.l
print("Perimeter of square is",p)
class Quad(Rect, Square):
def prt(self):
print('Rectangle and Square are quadrilaterals')
obq = Quad('Rectangle',10,20)
obq.display()
obq.R_area()
obq.peri()
obq.prt()
print(Quad.mro())
输出
Length is : 10 Breadth is : 20 Area of Rectangle is 200 Perimeter of square is 40 Rectangle and Square are quadrilaterals [<class '__main__.Quad'>, <class '__main__.Rect'>, <class '__main__.Square'>, <class '__main__.Shape'>, <class 'object'>]
类quad的MRO顺序是Quad ----> Rect ----> Square ----> Shape ----> Object。
Python提供了两种内置的继承方法来检查继承方法。它们是:
isinstance( object, type)
issubclass( object, class)
对于我们之前的例子,让我们看看内置方法是如何在Python中检查继承的。
x = isinstance(obq, Quad)
print(x)
x = issubclass(Rect,Shape)
print(x)
输出
True True