首页 > 解决方案 > 子类化、继承和子类选择

问题描述

我想构建一个类和子类,其中子类从超类继承一些方法。

到目前为止没有什么特别的,但我希望能够根据参数创建子类,例如这应该与示例代码中的a = Shape(sides=3, base=2, height=12)结果相同:c = Triangle(base=2, height=2)

class Shape:
    def __new__(cls, sides, *args, **kwargs):
        if sides == 3:
            print('a')
            return Triangle(*args, **kwargs)
        else:
            return Square(*args, **kwargs)

    def __init__(self, a):
        self._a = a

    @property
    def a(self):
        return self._a


class Triangle(Shape):
    def __init__(self, base, height):

        super().__init__(self, a='triangle')
        self.base = base
        self.height = height

    def area(self):
        return (self.base * self.height) / 2


class Square(Shape):
    def __init__(self, length):
        Shape.__init__(self, a='square')
        self.length = length

    def area(self):
        return self.length * self.length


a = Shape(sides=3, base=2, height=12)
b = Shape(sides=4, length=2)

c = Triangle(base=2, height=2)

print(c.a)

print(str(a.__class__))
print(a.area())

print(str(b.__class__))
print(b.area())

这会引发错误TypeError: __new__() missing 1 required positional argument: 'sides'

当我不继承类(做class Triangle:)时,它不会抛出错误,但我当然不能再使用该函数a了......

有什么提示吗?到目前为止,我的解决方案基于https://stackoverflow.com/a/60769071、https://stackoverflow.com/a/61509283https://www.code-learner.com/how-to-use-python -方法示例/

一种可能性是使用工厂模式,但我真的很喜欢覆盖功能的想法......

标签: pythonpython-3.xinheritancesubclass

解决方案


您正在继承&类Shape中的类,这将导致对类的无限递归调用。TriangleSquare__new__Shape

使用 Factory 类对您的代码进行了一些修改以实现它。

class Shape:
    def __init__(self, a):
        self._a = a

    @property
    def a(self):
        return self._a

class ShapeFactory:
    def __new__(cls, sides, *args, **kwargs):
        if sides == 3:
            print('a')
            return Triangle(*args, **kwargs)
        else:
            return Square(*args, **kwargs)


class Triangle(Shape):
    def __init__(self, base, height):

        super().__init__(a='triangle')
        self.base = base
        self.height = height

    def area(self):
        return (self.base * self.height) / 2


class Square(Shape):
    def __init__(self, length):
        Shape.__init__(self, a='square')
        self.length = length

    def area(self):
        return self.length * self.length


a = ShapeFactory(sides=3, base=2, height=12)
b = ShapeFactory(sides=4, length=2)

c = Triangle(base=2, height=2)

print(c.a)

print(str(a.__class__))
print(a.area())

print(str(b.__class__))
print(b.area())

推荐阅读