class繼承的一些知識
- Python 中的繼承
- Python 中的多重繼承
- super()原理
- 單繼承中的 作super()
- 多重繼承中的 作super()
如果 有使用面向對象語言的經驗, 已經熟悉super() 的功能。
子類可以通路p這綿超類(父類)中的方法。super()
單繼承
子類隻繼承一個父類:Square是單繼承的Rectangle
class Square(Rectangle):
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * self.length + 2 * self.width
# Here we declare that the Square class inherits from the Rectangle class
class Square(Rectangle):
def __init__(self, length):
super().__init__(length, length)
>>> square = Square(4)
>>> square.area()
可以看到 Square繼承 Rectangle類,自動擁有了你類的area方法
在此示例中,Square是超類(父類),并且Rectangle是子類。
super() 能做什麼
class Square(Rectangle):
def __init__(self, length):
super().__init__(length, length)
class Cube(Square):
def surface_area(self):
face_area = super().area()
return face_area * 6
def volume(self):
face_area = super().area()
return face_area * self.length
Square正方形類的長寬是相同的
def __init__(self, length):
super().__init__(length, length)
>>> cube = Cube(3)
>>> cube.surface_area()
54
>>> cube.volume()
27
super().__init__(length, length)
super()将委托對象傳回到父類,是以 可以直接在其上調用 的方法:。super().area()
其實很容易了解 super()代表的是父類代理對象,是以可以使用父類的相關方法。
深入探究super()
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * self.length + 2 * self.width
class Square(Rectangle):
def __init__(self, length):
super(Square, self).__init__(length, length)
這裡 Square在nit中直接指定父類Rectangle的init方法
super(Square, self).__init__(length, length)
繼續看下面的例子
class Cube(Square):
def surface_area(self):
face_area = super(Square, self).area()
return face_area * 6
def volume(self):
face_area = super(Square, self).area()
return face_area * self.length
face_area = super(Square, self).area()這裡我們使用了父類的area方法
super()在多重繼承中的作用
class Triangle:
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
class RightPyramid(Triangle, Square):
def __init__(self, base, slant_height):
self.base = base
self.slant_height = slant_height
def area(self):
base_area = super().area()
perimeter = super().perimeter()
return 0.5 * perimeter * self.slant_height + base_area
RightPyramid繼承了兩個類 Triangle,Square,并且這兩個父類都有area這個方法,下面的代碼會有問題。
>> pyramid = RightPyramid(2, 4)
>> pyramid.area()
Traceback (most recent call last):
File "shapes.py", line 63, in <module>
print(pyramid.area())
File "shapes.py", line 47, in area
base_area = super().area()
File "shapes.py", line 38, in area
return 0.5 * self.base * self.height
AttributeError: 'RightPyramid' object has no attribute 'height'
那麼子類會優先使用哪個父類的area方法呢?接着多繼承的方法查找順序
方法解析順序
類有一個屬性__mro__來觀察方法的查找順序
>>> RightPyramid.__mro__
(<class '__main__.RightPyramid'>, <class '__main__.Triangle'>,
<class '__main__.Square'>, <class '__main__.Rectangle'>,
<class 'object'>)
調用 area方法報錯可以看到AttributeError: 'RightPyramid' object has no attribute 'height'
說明它使用的是Triangle類中的area方法,通過觀察 __mro__的輸出發現查找順序是因為area同時在 Triangle,Square這兩個類中,但是它會按照下面的順序查找方法,是以會先使用Triangle中的area方法
RightPyramid-----> Triangle--> Square
未完待續
如何解決多繼承中的同名方法調用問題