3 回答

TA貢獻1835條經驗 獲得超7個贊
畢竟會把評論變成答案。處理你想要的事情的正確(Java)方法是使用接口。因此,在您的演示代碼中,實現如下:
public interface TheFGFunctions {
void f();
void g();
}
public class Tata implements TheFGFunctions {
@Override
public void f() {
//something
}
@Override
public void g() {
//something
}
}
public class Titi implements TheFGFunctions {
@Override
public void f() {
//something
}
@Override
public void g() {
//something
}
}
public class Toto {
private TheFGFunctions c;
public Toto(TheFGFunctions c) {
this.c = c;
}
public void notStaticFunction() {
c.f();
c.g();
}
}
這種方式是完全類型安全的,可以處理零異常!

TA貢獻1853條經驗 獲得超6個贊
您無法以多態方式訪問靜態方法。Java語言不支持它。
您當前的方法失敗的原因是它c
是類的實例Class
,并且該類Class
沒有定義方法f()
或g()
。
(它定義的方法列在 的javadocClass
中。請注意,這樣Class
您final
就無法使用額外的方法創建自定義子類。)
簡單的替代方法是使用反射;例如
Class c =?
? ? ?Method f = c.getMethod("f");
? ? ?f.invoke(null);? ?// because it is static
但請注意:
這不是靜態類型安全的。編譯器無法判斷您何時錯誤地嘗試
f()
在沒有此類方法的類上使用靜態。您需要處理一些例外情況;例如,缺少方法、不正確的簽名、非靜態方法、沒有正確訪問權限的方法。
其他答案建議創建一個接口和包裝類以使某些靜態方法可分派。它會工作,并且是編譯時類型安全的(?。?,但需要編寫大量樣板代碼。
@Michael Michailidis 評論道:
因此接口!
是的...有點。您只能對接口上聲明的實例方法進行多態分派。Tata
這意味著您必須擁有or的實例Titi
,并調用它的方法。我對這個問題的解讀是作者想避免這種情況。
(IMO,避免才是真正的問題。你最好不要試圖避免實例方法。)
FWIW,您可以在接口中聲明靜態方法(自 Java 8 起),但它們的行為與在類中聲明它們相同。你將無法發送...

TA貢獻1799條經驗 獲得超6個贊
編寫一個包裝接口
interface CWrapper {
void f();
void g();
}
以及包含方法的每個類的包裝類工廠方法
class CWrappers {
CWrapper forTiti(Class<Titi> titiClass) {
return new CWrapper() {
void f() { Titi.f(); }
void g() { Titi.g(); }
}
}
// another factory method for Tata
}
然后你可以使用它:
public class Toto {
private CWrapper c = CWrappers.forTata(Tata.class); //or forTiti(Titi.class)
public static void main(String[] args) {
c.f();
c.g();
}
}
添加回答
舉報