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();
}
}
添加回答
举报