在Java中用接口定义类的能力的实际方面是什么:
interface IFoo
{
class Bar
{
void foobar ()
{
System.out.println("foobaring...");
}
}
}
答案 0 :(得分:18)
我可以想到另一种用法,而不是Eric P链接的用法:定义接口的默认/无操作实现。
./亚历
interface IEmployee
{
void workHard ();
void procrastinate ();
class DefaultEmployee implements IEmployee
{
void workHard () { procrastinate(); };
void procrastinate () {};
}
}
另一个示例 - Null Object Pattern的实现:
interface IFoo
{
void doFoo();
IFoo NULL_FOO = new NullFoo();
final class NullFoo implements IFoo
{
public void doFoo () {};
private NullFoo () {};
}
}
...
IFoo foo = IFoo.NULL_FOO;
...
bar.addFooListener (foo);
...
答案 1 :(得分:8)
我认为this page很好地解释了一个例子。您可以使用它将某种类型紧密绑定到接口。
无耻地从上述链接中扯下来:
interface employee{
class Role{
public String rolename;
public int roleId;
}
Role getRole();
// other methods
}
在上面的界面中,您将Role类型强烈绑定到员工界面(employee.Role)。
答案 2 :(得分:6)
一个用途(无论好坏)将作为Java不支持接口中的静态方法这一事实的解决方法。
interface Foo {
int[] getData();
class _ {
static int sum(Foo foo) {
int sum = 0;
for(int i: foo.getData()) {
sum += i;
}
return sum;
}
}
}
然后你打电话给:
int sum = Foo._.sum(myFoo);
答案 3 :(得分:5)
我可以毫不犹豫地说我从未这样做过。我想不出你为什么会这么做的原因。嵌套在类中的类?当然,有很多理由这样做。在这些情况下,我倾向于认为那些内部类是一个实现细节。显然,接口没有实现细节。
答案 4 :(得分:3)
这个成语被大量使用的地方是XMLBeans。该项目的目的是获取XML Schema并生成一组Java类,您可以双向使用这些Java类来处理与模式相对应的XML文档。因此,它允许您将XML解析为xml bean或创建xml bean并输出到xml。
通常,大多数xml架构类型都映射到Java接口。该接口在其中包含一个Factory,用于在默认实现中生成该接口的实例:
public interface Foo extends XmlObject {
public boolean getBar();
public boolean isSetBar();
public void setBar(boolean bar);
public static final SchemaType type = ...
public static final class Factory {
public static Foo newInstance() {
return (Foo)XmlBeans.getContextTypeLoader().newInstance(Foo.type, null);
}
// other factory and parsing methods
}
}
当我第一次遇到这个时,将所有这个实现gunk绑定到接口定义似乎是错误的。然而,我实际上喜欢它,因为它让所有东西都根据接口定义,但有一个统一的方式来获取接口的实例(而不是有另一个外部工厂/构建器类)。
我选择了那些有意义的课程(特别是那些我对界面/ impls有很大控制权的课程)并发现它相当干净。
答案 5 :(得分:2)
我想你可以定义一个类,用作接口中方法的返回类型或参数类型。似乎没有特别有用。您也可以单独定义该类。唯一可能的优点是它在某种意义上将类声明为“属于”接口。
答案 6 :(得分:2)
Google Web Toolkit使用此类将“普通”接口绑定到异步调用接口:
public interface LoginService extends RemoteService {
/**
* Utility/Convenience class.
* Use LoginService.App.getInstance() to access static instance of LoginServiceAsync
*/
class App {
public static synchronized LoginServiceAsync getInstance() {
...
}
}
}
答案 7 :(得分:2)
通过接口内部的静态类,您可以缩短公共编程片段:检查对象是否是接口的实例,如果是,则调用此接口的方法。看看这个例子:
public interface Printable {
void print();
public static class Caller {
public static void print(Object mightBePrintable) {
if (mightBePrintable instanceof Printable) {
((Printable) mightBePrintable).print();
}
}
}
}
现在不是这样做的:
void genericPrintMethod(Object obj) {
if (obj instanceof Printable) {
((Printable) obj).print();
}
}
你可以写:
void genericPrintMethod(Object obj) {
Printable.Caller.print(obj);
}
答案 8 :(得分:1)
这样做似乎已经写好了“糟糕的设计决定”。
答案 9 :(得分:1)
每当创建非私有嵌套类似乎是个好主意时,我会小心谨慎。你几乎肯定会更好地直接去外地。但是如果你要创建一个公共嵌套类,那么将它放在接口而不是类中似乎并不奇怪。外部类的抽象性不一定与嵌套类的抽象性有关。
答案 10 :(得分:1)
此方法可用于在同一文件中定义许多类。在过去我有很多简单的接口实现,这对我来说效果很好。但是,如果我再次这样做,我会使用一个枚举来实现一个更优雅的解决方案。