我有2个班级,例如A和B.
这些类有几个具有相同名称的getter / setter方法。
现在在代码中我执行以下操作:
if(obj.getClassName().equals(A.class.getName())){
A a = (A) obj;
String result = a.getInfo();
}
else if(obj.getClassName().equals(B.class.getName())){
B a = (B) obj;
String result = a.getInfo();
}
我想知道是否有办法调用getInfo
来避免if语句
注意:我无法重构类以使用继承或其他东西
我只是感兴趣,如果在java中有一个技巧,以避免if语句。
答案 0 :(得分:6)
除非你想使用反射,否则没有。 Java将发生的两种类型视为完全独立的相同方法(getInfo()
),并采用完全独立的方法。
如果你有共性,你应该使用一个共同的超类或它们都继承的公共接口。您已经标记了“设计模式”这一问题 - 模式是使用该语言提供的工具来显示共性。
正如Eng.Fouad所示,无论如何使用instanceof
更简单 - 更好,因为这意味着您的代码仍然适用于A
或B
的子类。
你可以隔离这种丑陋,当然,把它放在一个地方 - 或者是一个可以用A
或{{1}构建的外观类通过一个执行此检查的方法,然后从多个位置调用它。
答案 1 :(得分:1)
如果你不能使用继承并希望避免使用if
语句(甚至使用instanceof
)......那么......你能做的最好就是包裹检查,投射和调用避免代码重复的功能......否则就无法做到这一点。
答案 2 :(得分:1)
您需要reflection。这是我的完整例子。
A类
package a;
public class A {
String info;
public String getInfo() {
System.out.println("A getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
B类
package a;
public class B {
String info;
public String getInfo() {
System.out.println("B getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
测试类
package a;
import java.lang.reflect.Method;
public class TestAB {
public static void main(String[] args) {
A a= new A();
doSth(a);
}
private static void doSth(Object obj) {
Class c = obj.getClass();
Method m;
try {
m = c.getMethod("getInfo", new Class[] { });
String result = (String) m.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
见这一行:
Class c = obj.getClass();
和
m = c.getMethod("getInfo", new Class[] { });
和
String result = (String) m.invoke(obj);
没有if
陈述
答案 3 :(得分:1)
如果obj声明为A或B,则可以使用重载方法。 (关于类型安全的一个很好的论据。)这是一个测试,说明了这一点:
import static org.junit.Assert.*;
import org.junit.Test;
public class FooTest {
class A {
public String getInfo() {
return "A";
}
}
class B {
public String getInfo() {
return "B";
}
}
public String doBarFor(A a) {
return a.getInfo();
}
public String doBarFor(B b) {
return b.getInfo();
}
public String doBarFor(Object obj) {
throw new UnsupportedOperationException();
}
@Test
public void shouldDoBarForA() {
A a = new A();
assertEquals("A", doBarFor(a));
}
@Test
public void shouldDoBarForB() {
B b = new B();
assertEquals("B", doBarFor(b));
}
@Test(expected = UnsupportedOperationException.class)
public void shouldFailIfDeclaredAsObject() {
Object a = new A();
assertEquals("A", doBarFor(a)); // exception thrown
}
}
答案 4 :(得分:0)
怎么样:
String result = null;
if(obj instanceof A)
{
result = ((A) obj).getInfo();
}
else if(obj instanceof B)
{
result = ((B) obj).getInfo();
}
答案 5 :(得分:0)
如果这是您想要实现的目标,请参阅:this tutorial。
答案 6 :(得分:0)
如果obj
是对象,则需要检查。如果您不想使用if语句,可以尝试只是转换并捕获异常:
String result = null;
try {
result = ((A)obj).getInfo();
}
catch(ClassCastException e1) {
try {
result = ((B)obj).getInfo();
}
catch(ClassCastException e2) {
// do something else
}
}
你可以做的另一件事是让两个类都实现一个接口,然后只检查那个接口,如:
public interface HasInfo
{
public String getInfo();
}
然后在A和B的类定义中添加implements HasInfo
。然后您可以检查(或转换)到HasInfo
。
答案 7 :(得分:0)
在Java中,您可以使用点作为范围解析运算符和静态方法。尝试这样的事情:
String a_info = A.getInfo();
String b_info = B.getInfo();
对于对象,如果两个接口实际上具有相同参数和相同返回类型的相同方法,为什么必须区别对待它们?看看here,了解更深入的问题。
祝你好运。