场景引入:在Android对系统API封装十分常见,为了易用性和覆盖性,很可能出现,接口的变参数定义。比如,fun(name = “example”), fun(name = “example”, age = 23)和fun(name = “example”, age = 23, address = “BeiJing”)。针对这个需求会有以下几种方案:
- 直接定义,三个接口,通过函数重载实现
- 通过函数默认参数实现
- 通过函数可变参数实现
分析说明:方法1会让函数数量爆炸式增加;方法2在Java中不支持,在Kotlin中支持,但似乎不支持继承携带默认参数;方法3则通过可变参数可以在Java里面通过尽可能少的方法实现多函数重载的功能,是一种折衷的实现。
举例如下:
public interface UiOperateAPI {
boolean clickViewByText(String text, int... timeout);
interface UiOperateExtAPI {
boolean clickViewByText(String text, int timeout, int sleepTime);
}
}
UiOperateAPI类中的clickViewByText的可变参数,通过一个接口实现了两个接口的clickViewByText(text = “text”)和clickViewByText(text = “text”, timeout = 1000)功能。另外,UiOperateAPI.UiOperateExtAPI这一嵌套接口扩展了三个参数的实现clickViewByText(text = “text”, timeout = 1000, sleepTime = 1000),这一个是为了规避可变参数会将所有传递的int数据封装到数组里面,但实际上却不想讲这些参数融合,否则只取可变参数的第一个参数,就会丢失数据了!
查看最终实现类:
public class UiOperateHelper implements UiOperateAPI, UiOperateAPI.UiOperateExtAPI {
@Override
public boolean clickViewByText(Pattern regex, int... timeout) {
UiObject2 viewByText = uiSearchImpl.findViewByText(regex, timeout);
return operateViewSafely(viewByText);
}
@Override
public boolean clickViewByText(String text, int timeout, int sleepTime) {
boolean ret = clickViewByText(text, timeout);
sleep(sleepTime);
return ret;
}
}
使用结论:后续在Android Studio中去搜索方法,可以发现只有两个接口,但是缺覆盖了三种参数类型的情况。
注意:Kotlin中增加参数默认值,也是比较方便的,但是Java中却不支持。
|