kotlin,如何简化向基类构造函数传递参数?

我们有一个包,我们正在寻求从python转换为kotlin,然后才能够使用该包迁移系统。

在这个包里面有一组类,它们是所有的变体,或者是一个公共基类的“风味”。

大部分代码都在基类中,它有大量的可选参数。 所以考虑:

打开class BaseTree(val height:Int = 10,val root:Boolean = true,// ……更多!

class FruitTree(val fruitSize, height:Int=10, roots:Boolean=true, // now need all possible parameters for any possible instance ):BaseTree(height=height, roots=roots //... yet another variation of same list 

代码实际上不是树,我只是认为这是一个简单的方式来传达这个想法。 基类有大约20个参数,大约有10个子类,每个子类有效地需要从基类重复相同的两个变量参数列表。 一个真正的噩梦,如果参数列表改变!

那些来自Java背景的人可能会评论“20个参数太多”,可能会错过这是可选参数 ,这是影响设计方面的语言特性。 20个必需的参数是疯狂的,但是10个或者甚至20个可选参数并不罕见,例如检查sqlalchemy表 。

在python中,你可以调用基类的构造函数:

 def __init__(self, special, *args, **kwargs): super().__init(*args, **kwargs) # pass all parameters except special to base constructor 

有没有人知道一种技术,使用不同的方法(也许使用接口或什么?),以避免重复这个参数列表反复每个子类?

你可以跳过像BaseTree(height, roots)这样的名字BaseTree(height, roots) ,把变量按顺序排列,但是你不能像Python那样做,因为Python是动态语言。

Java也必须将变量传递给超类。

 FruitTree(int fruitSize, int height, boolean root) { super(height, root); } 

基类有大约20个参数,大约有10个子类

这很可能是您的课程设计的问题。

如果你的子类真的在构造器中有很多参数 – >没有办法。 你需要全部通过。

但(主要)这是没有好的迹象,构造函数/函数有这么多参数…

你并不孤单。 这已经在gradle-slack频道上讨论过了。 也许在将来,我们会得到编译器的帮助,但现在,你需要自己传递参数。

没有设计模式来简化这个用例。

最佳解决方案:重构代码以使用更类似于Java的方法:使用属性代替可选参数。

使用案例解释:广泛使用的具有众多可选参数的类或方法在Java中是不实用的,而kotlin最为演化为使Java代码更好的方法。 一个带有5个可选参数的python类,没有可选参数,转换为Java,可能有5个! (和5因子是60 )不同的Java签名…换句话说是一团糟。

很明显,没有对象应该常规地用一个巨大的参数列表来实例化,所以当大多数调用不需要指定这些可选参数时,规范的python类只会演化为类,而可选参数是针对异常情况的。 这里的实际使用情况是大量可选参数的实现,在这里使用超过3个可选参数来实例化任何单个对象应该是非常罕见的。 因此,一个具有10个可选参数的类在应用程序中被使用了500次,仍然期望3个可选参数是在一个实例中有史以来使用的最大值。 但是,这只是一种设计方法,无论Java多久重用一次,都无法在Java中使用。

在Java中,函数hot有可选参数,这意味着这种情况下,在Java库中以这种方式实例化对象根本不可能发生。

考虑一个具有一个强制实例参数的对象,以及五个可能的选项。 在Java中,这些选项都是属性,可以由setter设置,然后对象将被实例化,setter()调用设置任何相关选项,但很少需要更改该选项的默认值。

缺点是这些选项不能从构造函数中设置,并保持不变,但最终的代码减少了可选参数。

另一种方法是使用一组不太“瑞士军刀”的对象,用一套专门的工具代替一个“全能工具”,即使代码可能被看作是同一主题的细微差别。

尽管支持kotlin中的Optional参数,但kotlin中的继承结构尚未针对此功能的更多使用进行优化。

Interesting Posts