【问题标题】:Inheritance in Python with Different Argument(s)具有不同参数的 Python 中的继承
【发布时间】:2019-04-19 16:31:31
【问题描述】:

当子类从超类继承时,子类必须具有超类具有的所有参数吗?例如:“Vehicle(color,wheels,size)”是超类。除了“大小”属性/参数之外,我可以有一个从 Vehicle 继承所有内容的子类吗?

这是父类:

class LagStudent:

    def __init__(self, name, dept, cgpa, is_a_scholar):
        self.name = name
        self.dept = dept
        self.cgpa = cgpa
        self.is_a_scholar = is_a_scholar

以下是两个子类:

class CovStudent(LagStudent):

    def __init__(self, name, dept, cgpa, is_a_scholar, honours):
        super().__init__(name, dept, cgpa, is_a_scholar)
        self.honours = honours


class OxStudent(CovStudent):

    def __init__(self, name, dept, cgpa, is_a_scholar):
        super().__init__(name, dept, cgpa, is_a_scholar) 

当我运行以下...

student4 = OxStudent("Mark", "Mathematics", 4.62, True)
print(student4.is_a_scholar)

它给出错误:

TypeError: init() 缺少 1 个必需的位置参数:'honours'

【问题讨论】:

  • 问题不清楚:子类方法应该如何表现?他们不能调用父 Vehicle 方法,因为他们需要 size 作为参数。
  • 是的,当然你可以。问题是,你应该吗?
  • 为什么OxStudent在这里继承CovStudent而不是LagStudent

标签: python python-3.x inheritance


【解决方案1】:

我们定义Vehicle超类如下,Bicycle子类如下

class Vehicle:

    def __init__(self, colour, wheels, size):

        self.colour = colour
        self.wheels = wheels
        self.size = size

class Cycle(Vehicle):

    def __init__(self, colour, wheels, size):

        super().__init__(colour, wheels, 'small')

在这里您可以看到 Cycle 子类只接受 colorswheels 并将其传递给超类,并且具有硬编码的 size=small 属性。子类构造函数调用超类的构造函数

要检查发生了什么,我们可以尝试如下:

veh = Cycle('Black', 2)
print(veh.colour)
print(veh.wheels)
print(veh.size)
#Black
#2
#small

更新 基于 OP 的不希望有 size 属性的评论,您可以为超类中的 size 属性分配默认值,例如size=None 并且在实例化子类时不需要传递它。

class Vehicle:

    def __init__(self, colour, wheels, size=None):

        self.colour = colour
        self.wheels = wheels
        self.size = size

class Cycle(Vehicle):

    def __init__(self, colour, wheels):

        super().__init__(colour, wheels)

然后您可以按如下方式调用它

veh = Cycle('Black', 2)
print(veh.colour)
print(veh.wheels)
print(veh.size)
#Black
#2
#None

您可以看到size 的值是None,这是我们选择的默认值,因为我们没有显式传递size,如果我们传递它,我们就会得到一个值size属性

【讨论】:

  • 好的,我的意思是:如果我不希望 Cycle 具有“大小”属性怎么办。构造类时是否可以省略它,或者即使我不希望该类的实例具有“大小”属性,我也必须包含它?
  • 好的,我已经更新了我的答案以包含那个场景!
  • 这就是我的意思。现在的问题是程序没有运行。它给出了这个错误:在 init super().__init__(colour,wheels) TypeError: __init__() missing 1 required positional argument: 'size'
  • 你能说明你正在实例化哪个类以及你是如何实例化它的
  • 我已经编辑了我原来的问题。请看你是否明白我的意思。谢谢。
【解决方案2】:

对于__init__ 方法,子类当然可以有与其超类不同的签名。它只需要调用它的超类的__init__ 方法,使用该方法所期望的:

class Vehicle:
    def __init__(self, colour, wheels, size):
        self.colour = colour
        self.wheels = wheels
        self.size = size

class Car(Vehicle):
    def __init__(self, colour, wheels):
        super().__init__(colour, wheels, 'small')

print(Car('white', 4).size)

这个输出:

small

【讨论】:

  • 感谢您的回复,但我真正想知道的是:如果我不希望“汽车”类具有“尺寸”属性怎么办?是否可以在类构造和继承初始化中都省略它?
  • @Goriola,那么它不是真正的子类,是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
相关资源
最近更新 更多