Python 多态性

标签 python oop inheritance polymorphism

一位讲师给我布置了一项任务,试图用 Python 教授 OOP。我非常熟悉 C++ 和 C# 中的 OOP,但很难弄清楚我的一些 code 中发生了什么。 .它可以工作,并且两个类都可以按我想要的方式运行,但我必须添加一些奇怪的代码才能工作,但我不明白为什么。

具体引用第64行开始的代码

class Cone(Cylinder):

    #Constructor
    def __init__ (self, radius, height):        
        Cylinder.__init__(self, radius, height)
        self.calcVolume()


    def calcVolume(self):
        Cylinder.calcVolume(self)
        self.__volume = Cylinder.GetVolume(self) * (1.0/3.0)

因此,在实现 Cone 时,我不明白为什么当圆锥体的构造函数调用圆柱体的构造函数时,没有调用 Cylinder.calcVolume()。如果代码被隐式调用但我被迫显式调用该方法,则代码对我来说更有意义。一些指导或解释会很棒。

在发布后我做了这个改变是否更有意义?

class Cone(Cylinder):

    #Constructor
    def __init__ (self, radius, height):        
        Cylinder.__init__(self, radius, height)
        self.calcVolume()


    def calcVolume(self):
        self.__volume = self.GetBase().GetArea() * self.GetHeight() * (1.0/3.0)

最佳答案

这是调用 Cone.__init__() 时发生的情况:

  • 它执行 Cylinder.__init__()
  • 依次调用 self.calcVolume(),
  • 因为继承,解析顺序在Cone类型上找到方法,
  • 它调用 Cone.calcVolume() 而不是 Cylinder.calcVolume()

__init__() 期间我想你想调用:

  • Cone.calcVolume(self)Cone.__init__() 中,或者
  • Cylinder.calcVolume(self)Cylinder.__init__() 中。

当然,如果您正在使用新样式类(继承自 object),那么您可以只使用 type(self).calcVolume(self);但是,旧式类上的 type(self) 将为您提供 instance 类型,而不是实际的类,这在您的情况下不起作用。


完整示例:

class Circle():
    #Constructor
    def __init__ (self, radius):
        self.__radius = radius
        self.calcArea()
    def calcArea(self, PI = 3.14):
        self.__area = (self.__radius**2) * PI
    #Get Functions
    def GetArea(self):
        return self.__area
    def GetRadius(self):
        return self.__radius
    #Set Functions
    def SetRadius(self, radius):
        self.__radius = radius
        self.calcArea()

class Cylinder():
    #Constructor
    def __init__(self, radius, height):
        self.__height = height
        self.__base = Circle(radius)
        Cylinder.calcVolume(self)
    def calcVolume(self):
        self.__volume = self.__base.GetArea() * self.__height
    #Get Functions
    def GetVolume(self):
        return self.__volume
    def GetBase(self):
        return self.__base
    def GetRadius(self):
        return self.__base.GetRadius()
    def GetHeight(self):
        return self.__height
    #Set Functions
    def SetRadius(self, radius):
        self.__base.SetRadius(radius)
        self.calcVolume()
    def SetHeight(self, height):
        self.__height = height
        self.calcVolume()


class Cone(Cylinder):
    #Constructor
    def __init__ (self, radius, height):
        Cylinder.__init__(self, radius, height)
        Cone.calcVolume(self)
    def calcVolume(self):
        Cylinder.calcVolume(self)
        self.__volume = Cylinder.GetVolume(self) * (1.0/3.0)
    #Get Functions
    def GetVolume(self):
        return self.__volume
    #Set Functions
    def SetRadius(self, radius):
        Cylinder.SetRadius(self, radius)
        self.calcVolume()
    def SetHeight(self, height):
        Cylinder.SetHeight(self, height)
        self.calcVolume()


def main():
        cylinder = Cylinder(5, 6)
        cone = Cone(5, 6)
        circle = Circle(5)
        print cylinder.GetVolume()
        print cone.GetVolume()
        print circle.GetArea()
        cone.SetHeight(7)
        print cone.GetVolume()

main()

关于Python 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17690464/

相关文章:

c++ - 如何在基类型引用中存储对派生类型的引用?

javascript - 使用 Selenium 关闭浏览器弹出窗口

python - while、if 和 for 循环。 Python 上的第一个字母,最后一个字母游戏

python - Pandas 蟒 : Writing output to specific cells in the CSV

java - 如何在 toString() 方法中返回 2 前导 0?

java - 我们为什么要覆盖一个方法?

java - 面向对象编程私有(private)类字段+获取/设置或公共(public)类字段?

java - 方法链 + 继承不能很好地结合在一起?

jquery - Python从两个表中获取数据

c# - 如何在 C# 中使用派生类型覆盖泛型方法