如何在不同的类中共享相同的构造函数,也就是在接口中定义构造函数?

时间:2017-05-22 02:00:11

标签: android kotlin

假设我在Android中有多个具有相同构造函数的自定义视图

class Button: AppCompatButton {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
    //Some custom implementation
    //............
}

class TextView: AppCompatTextView {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
    //Some custom implementation
    //............
}

所以我需要一些接口或基类,它允许我继承多个视图,如TextView,Button,EditText等。

这样的东西
abstract class BaseView<T : View> : T {
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
}

或者

interface ViewConstructor {
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
}

所以我只使用一个界面或基类,不要一次又一次地复制过去的承包商。如何在Kotlin实现这样的目标?

P.S。请不要建议使用基类作为View并使用基类创建派生视图。我正在使用XML,我需要EditText,Button和其他视图。

2 个答案:

答案 0 :(得分:4)

编辑:我只是偶然发现了这个答案,需要更新。在某些自定义视图中使用@JvmOverloads可能是一个问题,因为调用为您自己的类生成的任何构造函数将首先委托给类中的all-params构造函数,然后调用super的all-params构造函数。而不是每个构造函数使用匹配的参数量调用super方法。有关详细信息,请参阅this article(例如)。

我的答案的原文如下。

作为必须编写许多构造函数的解决方案,您可以使用默认参数与@JvmOverloads结合使用来轻松获取所有4个View构造函数,同时只为您的类编写主构造函数:

class CustomView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0,
        defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {

}

答案 1 :(得分:0)

您极不可能找到问题的解决方案。首先,构造函数不会以您建议的方式继承。它们用于初始化继承链的一部分,因此从您继承的任何人仍然需要转发到超类构造函数。我很确定你在每个View类中都重新声明了那些视图构造函数(尽管其中一些可能会根据你的实例化用例而丢弃)。