【问题标题】:When must I use super() to call superclass methods?什么时候必须使用 super() 来调用超类方法?
【发布时间】:2020-07-25 17:28:49
【问题描述】:

我明白为什么我为 ElectricCar 类调用 super(),以便能够调用父 Car 类定义的方法。但是为什么我不必调用 super() 来调用 Battery 类方法,例如 my_tesla.battery.describe_battery()?

我正在学习此示例的 Python Crash Course。

from default_attributes import Car


class Battery:
    """A simple attempt to model a battery for an electric car"""

    def __init__(self, battery_size=75):
        """Initialize the batter's attributes"""
        self.battery_size = battery_size

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-KWh battery.")

    def get_range(self):
        """Print a statement about the range this battery provides"""
        if self.battery_size == 75:
            range = 260
        elif self.battery_size == 100:
            range = 315

        print(f"This car can go about {range} miles on a full charge.")


class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles"""

    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery = Battery()

    def fill_gas_tank(self):
        # Overide parent methods by defining one with the same name.
        """Electric cars don't have gas tanks"""
        print("This car doesn't need a gas tank!")


my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

【问题讨论】:

  • Battery 没有超类。
  • @szatkus 那我一定是想错了。我会认为 Battery 会被视为 my_tesla.battery 的超类
  • 这段代码中唯一的超类是Car,因为ElectricCar继承自它。
  • 一个ElecticCar 一个Car,但有一个一个Battery。每个类都称为方法解析顺序 (MRO),它是在其继承层次结构中找到的类的线性序列。 super 提供了一种方法来调用 MRO 中“下一个”类的方法,具体取决于当前正在执行的方法。
  • Battery 只是值my_tesla.battery

标签: python


【解决方案1】:

我认为您正在做的是将继承与组合混为一谈。这是一个很好的article 关于两者之间的区别。每当你继承一个类时,你都需要调用super。每当您与另一类(电池)组成一个类(电动汽车)时,您都不会。这有帮助吗?

【讨论】:

    【解决方案2】:

    欢迎来到 SO。

    您只需调用super 即可访问您的子类覆盖的方法(,具有相同名称的方法)。超类定义且子类未覆盖的方法可以作为实例的方法调用(或者如果您提供显式实例作为第一个参数,则作为类的方法),因为它们是继承的,但是在本地定义方法意味着本地方法在超类中的定义之前找到。

    以下程序可能会解释这种混淆:

    class SuperClass():
        def non_overridden(self):
            print("SuperClass non_overridden")
        def overridden(self):
            print("SuperClass overriden")
    
    class SubClass(SuperClass):
        def overridden(self):
            print("SubClass overriden")
        def do_it_all(self):
            super().overridden()
            self.overridden()
            self.non_overridden()
    
    sc = SubClass()
    sc.do_it_all()
    

    Python 的发明者的正式explanation of Python's method resolution process 值得一读,而且在今天仍然非常有效。

    【讨论】:

    • 非常感谢。这本书没有涉及到这一点,所以这很有帮助。
    • 不确定你在看什么书,但这是相当标准的面向对象的东西。很高兴它有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2011-11-28
    • 2011-05-04
    • 2017-03-22
    • 2014-03-27
    相关资源
    最近更新 更多