我需要一种方法来接受两种类型并对它们执行相同的操作。
我知道我可以做到:
public void myMethod(TextView tv, ReadableMap styles) {
if (styles.hasKey("fontFamily")) {
String font = "fonts/" + styles.getString("fontFamily") + ".ttf";
Typeface tf = Typeface.createFromAsset(context.getAssets(), font);
tv.setTypeface(tf);
}
if (styles.hasKey("fontSize")) {
tv.setTextSize(styles.getInt("fontSize"));
}
if (styles.hasKey("letterSpacing")) {
tv.setLetterSpacing(PixelUtil.toPixelFromDIP(styles.getInt("letterSpacing")));
}
}
public void myMethod(TextPaint tv, ReadableMap styles) {
// copy paste the **exact** same code
}
TextView
和TextPaint
都有方法setTypeface(Typeface)
,setTextSize(float)
和setLetterSpacing(float)
,但是两个类除了{{1 }}。 (请注意,Object
继承了TextPaint
的方法。)这两个类都分别声明了这些方法,并具有相同的名称和签名。
因此,由于我无法相互转换,所以我想知道如何减少重复代码的数量?
答案 0 :(得分:1)
创建一个共享通用方法签名setTypeFace
,setTextSize
,setLetterSpacing
的接口类。 (基本上是适配器模式。)
public interface MyInterface {
Typeface setTypeface(Typeface typeface);
void setTextSize (float textSize);
void setLetterSpacing(float letterSpacing);
}
将myMethod签名重新定义为
public void myMethod (MyInterface myi, ReadableMap styles) {
//...change all your 'tv' references to myi
}
然后使用匿名类进行调用
// myTextView is in scope here...
myMethod(new MyInterface() {
// partial implementation
Typeface setTypeface(Typeface typeface) {
myTextView.setTypeface(typeface);
}, myStyles);
}
// myTextPaint is in scope here
myMethod(new MyInterface() {
// partial implementation
Typeface setTypeface(Typeface typeface) {
myTextPaint.setTypeface(typeface);
}, myStyles);
}
或创建同时为TextView和TextPaint实现MyInterface的包装器类。
答案 1 :(得分:0)
我对我的评论表示歉意,我应该检查超类,并应该使用使我的观点清晰可见的词而不是断言。为了解决这个问题,我尝试了以下方法,并且确实有效。由于目前没有可用的Android SDK,因此我创建了自己的TextView和TextPaint类,并使用 reflection 调用方法,因为我们已经知道它们的签名。
首先,将您的方法签名更改为public void myMethod(Object tv, ReadableMap styles)
。
这显示了如何调用setTextSize
方法,但是所有其他方法的概念也应相同。
tv.getClass()
.getMethod("setTextSize", float.class)
.invoke(tv, styles.getInt("fontSize"));
您可以了解有关invoking methods via their names using Java Reflection的更多信息。
答案 2 :(得分:0)
怎么样
public void myMethod(TextView tv, String styles, TextPaint tp) {
//must tv == null -> tp != null or tv != null -> tp == null
if(tv != null){
tp = tv.getPaint();
}
//doSomthing
}
答案 3 :(得分:-2)
这很容易解决,但是您需要了解多态性的基本概念。
为了做到这一点,您需要在这两种类型之间有一个共同的祖先。
public void myMethod(TextView tv, ReadableMap styles) {this.method(tv,styles);}
public void myMethod(TextPaint tv, ReadableMap styles) {this.method(tv,styles);}
private void method(CommonAncestor tv, ReadableMap styles){/*do your stuff*/}
您的两个班级Class
或Interface
的共同祖先是extends
或implements
此祖先必须同时提供您要调用的常用方法
如果要在项目中创建这些类,则可以简单地创建祖先并将其扩展
如果它们是内置类型,则可以检查它们的树线并查找是否两个类共享一个具有相同名称和逻辑的方法,通常它们共享一个祖先变量