如何构建行为相同但参数不同的类层级结构?
处理不同参数的统一行为层级结构方案
针对你提到的类A、B、C需要统一行为但执行方法参数不同的问题,有几种可行的方案可以将它们纳入同一层级结构,以下是具体实现:
1. 泛型接口+密封类封装参数(推荐方案)
核心思路是把每个类的perform参数封装成专属的数据类,通过泛型接口将所有类统一起来,同时保证类型安全。
以Kotlin为例实现:
// 用密封类统一管理所有执行参数类型,确保类型封闭性 sealed class PerformParams { data class TwoInts(val value1: Int, val value2: Int) : PerformParams() data class StringList(val entries: List<String>) : PerformParams() data class SingleString(val value1: String) : PerformParams() } // 定义泛型行为接口,绑定参数类型 interface Performable<T : PerformParams> { fun canPerform(params: T): Boolean fun perform(params: T) } // 类A实现接口,指定对应参数类型 class A : Performable<PerformParams.TwoInts> { override fun canPerform(params: PerformParams.TwoInts): Boolean { return params.value1 > 0 && params.value2 > 0 } override fun perform(params: PerformParams.TwoInts) { println("A执行操作:计算两数之和=${params.value1 + params.value2}") } } // 类B实现接口 class B : Performable<PerformParams.StringList> { override fun canPerform(params: PerformParams.StringList): Boolean { return params.entries.isNotEmpty() } override fun perform(params: PerformParams.StringList) { println("B执行操作:处理字符串列表=${params.entries.joinToString(",")}") } } // 类C实现接口 class C : Performable<PerformParams.SingleString> { override fun canPerform(params: PerformParams.SingleString): Boolean { return params.value1.isNotBlank() } override fun perform(params: PerformParams.SingleString) { println("C执行操作:处理字符串=${params.value1}") } }
这个方案的优势:
- 严格的类型安全,编译期就能避免参数类型错误
- 所有类都实现了同一泛型接口,自然纳入同一层级
- 参数封装后,
canPerform可以直接针对专属参数做合法性校验
2. 通用接口+类型检查(应急方案)
如果不想封装参数,可以定义一个接受任意类型参数的接口,在实现类中通过类型检查处理参数,但这种方式会丢失类型安全,仅适合临时场景:
interface Performable { fun canPerform(params: Any): Boolean fun perform(params: Any) } class A : Performable { override fun canPerform(params: Any): Boolean { return params is Pair<Int, Int> && params.first > 0 && params.second > 0 } override fun perform(params: Any) { if (params is Pair<Int, Int>) { println("A执行操作:${params.first + params.second}") } else { throw IllegalArgumentException("A需要Pair<Int, Int>类型参数") } } }
缺点很明显:编译期无法检查参数类型,运行时容易抛出异常,代码维护成本高。
3. 标记接口+策略管理器(保留原有方法签名)
如果必须保留每个类原有perform方法的参数签名,可以用标记接口将所有类归为同一类型,再通过管理器统一调度:
// 仅作为标记,无方法定义 interface PerformableMarker class A : PerformableMarker { fun canPerform(value1: Int, value2: Int): Boolean { return value1 > 0 && value2 > 0 } fun perform(value1: Int, value2: Int) { println("A执行操作:${value1 + value2}") } } class B : PerformableMarker { fun canPerform(entries: List<String>): Boolean { return entries.isNotEmpty() } fun perform(entries: List<String>) { println("B执行操作:${entries.joinToString()}") } } // 管理器负责处理不同类型的实例 class PerformManager { fun execute(marker: PerformableMarker, vararg args: Any) { when (marker) { is A -> { if (args.size == 2 && args[0] is Int && args[1] is Int) { val v1 = args[0] as Int val v2 = args[1] as Int if (marker.canPerform(v1, v2)) marker.perform(v1, v2) } } is B -> { if (args.size == 1 && args[0] is List<*>) { val entries = args[0] as List<String> if (marker.canPerform(entries)) marker.perform(entries) } } // 处理C... } } }
这种方式保留了原有方法的直观性,但管理器需要不断扩展when分支,扩展性一般,适合类数量不多的场景。
内容的提问来源于stack exchange,提问作者LeYAUable
相关产品推荐
相关产品推荐

