【问题标题】:create 2 identical classes of different subtype创建 2 个不同子类型的相同类
【发布时间】:2018-01-11 01:17:15
【问题描述】:

我使用一个要求我创建 2 个类的 Android 库, 每个继承自不同的类。
(具有共同的基类)

现在我有这个代码:

类 IncomingFileMVH(itemView: 视图): Lib.IncomingTextMVH(itemView) { 私人 val tv: TextView = itemView.findViewById(R.id.text) 覆盖 fun onBind(message: ChatMessage) { super.onBind(消息) tv.text = message.text } }

我必须复制这个类来创建一个扩展Lib.OutcomingTextMVHOutcomingFileMVH,即使我的两个类共享完全相同的代码。

我简化了示例的代码,但重复部分可能很重要。
我决定将我的代码放在这两个类之外的静态方法中, 并在类重写方法中调用它们,但我认为必须有一种更清洁的方法来做到这一点。

你能帮我解决这个问题吗?

Lib.OutcomingTextMVHLib.IncomingTextMVH 都继承自 Lib.BaseMVH

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    我看到了一种解决方案,但如果onBind 多次调用它可能效率不高。将此代码放在一个文件中,以确保共享逻辑不会暴露在其他任何地方:

    class IncomingFileMVH(itemView: View):
    Lib.IncomingTextMVH(itemView) {
    
        override fun onBind(message: ChatMessage) {
            super.onBind(message)
            bind(message) //Import extension method from Shared
        }
    }
    
    class OutcomingFileMVH(itemView: View):
    Lib.OutComingTextMVH(itemView) {
    
        override fun onBind(message: ChatMessage) {
            super.onBind(message)
            bind(message)
        }
    }
    
    private object Shared {
    
        val Lib.BaseMVH.tv: TextView
            get() = itemView.findViewById(R.id.text)
    
        fun Lib.BaseMVH.bind(message: ChatMessage) {
            tv.text = message.text
        }
    }
    

    粗略地说,这里的问题是我们不能在扩展属性中存储任何值。所以每次调用onBind时,它也会调用itemView.findViewById(R.id.text)

    还有另一种我更喜欢的解决方案。为属性创建契约接口,为两个类实现它并为onBind()创建辅助扩展方法

    private interface Base {
    
        val tv: TextView
    }
    
    class IncomingFileMVH(itemView: View):
    Lib.IncomingTextMVH(itemView), Base {
    
        override val tv: TextView = itemView.findViewById(R.id.text)
    
        override fun onBind(message: ChatMessage) {
            super.onBind(message)
            bind(message)
        }
    }
    
    class OutcomingFileMVH(itemView: View):
    Lib.OutComingTextMVH(itemView), Base {
    
        override val tv: TextView = itemView.findViewById(R.id.text)
    
        override fun onBind(message: ChatMessage) {
            super.onBind(message)
            bind(message)
        }
    }
    
    private fun Base.bind(message: ChatMessage) {
        tv.text = message.text
    }
    

    是的,您需要使用View 复制所有属性,但与之前一样,所有绑定逻辑都放在单个方法中,并且所有属性都初始化一次

    【讨论】:

    • 谢谢,我用接口解决方案试了一下,之前没有发现变量覆盖的东西。
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2022-01-16
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多