class Date(datetime.date):
def __init__self(self, year, month, day):
super().__init__(year, month, day)
假设我创建了一个继承自datetime.date
的类,并且我想重新定义__init__
方法,因此不要采用参数year
,month
和{{1} },以获取字符串day
,对其进行解析,并以超级s
方法传递解析后的变量。像这样:
__init__
这种做法正确吗?我的意思是在实践中使用这种做法吗?
答案 0 :(得分:1)
从技术上讲,您可以做到。但是根据Liskov substitution principle,祖先的界面应类似于其父代的界面(但祖先的界面可以更宽)。在您的情况下,以s
作为参数的类不能在传递year
,month
和day
的上下文中使用。因此这种方法不是很好。
但是,如果使祖先的构造函数更复杂,则可以实现此目的:
class Date(datetime.date):
def __init__self(self, year=None, month=None, day=None, s=None):
if s is None:
args = year, month, day
else:
args = self.parse(s)
super().__init__(*args)
但是对于我来说,我会保持简单并实现类似这样的方法:
class Date(datetime.date):
def __init__self(self, year, month, day):
super().__init__(year, month, day)
@classmethod
def parse(cls, s):
args = ...
return cls(*args)
(正如@Mike Housky已经提到的那样,可以忽略这样一个琐碎的构造函数;我只是为了使我的例子更清楚而写了它)
答案 1 :(得分:0)
对基类__init__
方法的调用既正确又必要。如果子类没有子类,Python只会调用超类__init__
方法。
Python将让您忽略该super().__init__
调用,但这将使超类未初始化。那不是真正的继承。或者,也许不是真正的OOP,因为您假设继承的方法在不调用基类的__init__
的情况下就可以工作,并且破坏了封装。无论哪种方式,都不是OOP。
将不同的参数传递给超类__init__()
方法也很常见。子类通常需要其他信息。
在您的示例中,最棘手的是在对象完全初始化之前调用self.parse()
。如果那是您自己的方法(稍后在Date
类中定义),则它可能应该是类方法,而不是实例方法。如果它是从datetime.date
继承的实例方法,则不能保证它会起作用。