簡體   English   中英

Java並避免使用相似方法的對象的if語句

[英]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無論如何都更簡單-而且更好,因為這意味着您的代碼仍然可以與AB子類一起使用。

當然,您可以通過將丑陋放在一個地方來隔離這種丑陋-使用可以從AB構造的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM