我有一个类层次结构:
class ParentClass:
def do_something(self):
pass # child classes have their own implementation of this
class ChildClass1(ParentClass):
def do_something(self):
<implementation here>
class ChildClass2(ParentClass):
def do_something(self, argument_x):
<implementation here>
class ChildClass3(ParentClass):
def do_something(self, argument_y):
<implementation here>
Run Code Online (Sandbox Code Playgroud)
这里有两个问题:
这是类的使用方式:
有一个返回实例的工厂类:
class ChildFactory:
def get_child(self, argument):
if argument == '1':
return ChildClass1()
elif argument == '2':
return ChildClass2()
elif argument == '3':
return ChildClass3()
Run Code Online (Sandbox Code Playgroud)
稍后在代码中:
...
# pseudocode, not python
child_type = ? # can have values '1', '2' or '3' at this moment
var1 = 1
var2 = 'xxx'
# var1 and var2 have different types, just to emphasize the difference in their
# meaning when being passed as arguments to do_something()
# this was mentioned above (the second problem)
child = ChildFactory.get_child(child_type)
if child is an instance of ChildClass1, child.do_something() is called
if child is an instance of ChildClass2, child.do_something(var1) is called
if child is an instance of ChildClass3, child.do_something(var2) is called
# end of pseudocode
Run Code Online (Sandbox Code Playgroud)
问题:
S.L*_*ott 10
具有相同名称和不同参数的方法是代码气味.
"方法do_something()在子类中有不同的接口:它接受子类2和3中的参数,但在子类1中没有参数"
你不说为什么.有两个很好的理由
子类1具有默认值.
子类2忽略了该值.
几乎任何其他原因都表明它do_something
是真正不同的,应该有不同的名称.
如果子类1具有默认值,则只需在方法函数的参数中显式编写默认值.
class ChildClass1( ParentClass ):
def do_something( argument_x= None )
....
Run Code Online (Sandbox Code Playgroud)
如果子类1忽略该值,则只需忽略该值.不要站在你的头上忽略一个角.
class ChildClass1( ParentClass ):
def do_something( argument_x )
return True
Run Code Online (Sandbox Code Playgroud)
没有使用所有参数值的多态方法函数没有魔力.
"do_something()的参数有不同的名称,以强调它们在子类2和3中有不同的含义."
这只是糟糕的设计.您不能使用具有不同参数名称的相同方法函数,因为它们执行不同的操作.
拥有相同的方法函数名称是错误的.如果它们是类似事物的不同实现,那么参数将具有基本相同的含义.
如果他们实际上做了不同的事情,那么你没有多态性,你不应该给这些方法赋予相同的名称.
当两个类中的方法做了根本不同的事情 - 需要具有不同名称的不同参数以使其显而易见时 - 这些方法必须不具有相同的名称.当名称没有描述该方法实际执行的内容时,该名称就不再具有意义.
注意
你的代码BTW将在Python中运行,因为鸭子打字.只要方法名称匹配,参数类型就不必接近匹配.然而,这是非常糟糕的设计,因为这些方法之间的本质区别是如此巨大.