[英]Java and avoid if statements for objects with similar methods
我有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();
}
我想知道是否有一種方法可以避免使用if語句來調用getInfo
。
注意:我無法重構類以使用繼承或其他方法。
我只是想知道Java中是否有技巧來避免if語句。
除非您要使用反射,否則。 Java將碰巧聲明同一方法( getInfo()
)的兩種類型完全分開,並使用完全分開的方法。
如果具有通用性,則應使用它們都繼承的通用超類或通用接口。 您已經標記了“設計模式”問題-模式是使用該語言提供的工具來顯示通用性。
正如Eng.Fouad所示,使用instanceof
無論如何都更簡單-而且更好,因為這意味着您的代碼仍然可以與A
或B
子類一起使用。
當然,您可以通過將丑陋放在一個地方來隔離這種丑陋-使用可以從A
或B
構造的Facade類,或者通過執行此檢查的單個方法,然后從中調用多個地方。
如果您不能使用繼承並且想要避免if
語句(甚至使用instanceof
)...那么...您可以做的最好的事情就是包裝檢查,強制轉換和調用函數以避免代碼重復...否則沒有辦法做到這一點。
你需要反思 。 這是我完整的示例。
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
語句
如果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
}
}
怎么樣:
String result = null;
if(obj instanceof A)
{
result = ((A) obj).getInfo();
}
else if(obj instanceof B)
{
result = ((B) obj).getInfo();
}
如果您要達到此目的,請參考: 本教程 。
如果obj
是一個Object,則需要檢查。 如果您不想使用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
)為HasInfo
。
在Java中,可以將點用作靜態方法的范圍解析運算符。 嘗試這樣的事情:
String a_info = A.getInfo();
String b_info = B.getInfo();
對於對象,如果兩個接口確實具有相同的方法,相同的參數和相同的返回類型,為什么必須區別對待它們? 在這里查看有關此問題的更多信息。
祝好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.