Java 标识对象功能的标记接口或布尔方法?

Java 标识对象功能的标记接口或布尔方法?,java,oop,properties,api-design,marker-interfaces,Java,Oop,Properties,Api Design,Marker Interfaces,我正在开发一个更大的Java类层次结构,其中一些类具有我在运行时感兴趣的特定属性(该属性肯定只适用于类,而不适用于特定实例) 我可以创建一个抽象布尔方法isFooBar(),子类可以实现该方法来指示属性是否存在: public abstract class MyBaseClass { ... public abstract boolean isFooBar(); } 或者,我也可以使用标记接口FooBarProperty,并对接口执行instanceof检查: public class

我正在开发一个更大的Java类层次结构,其中一些类具有我在运行时感兴趣的特定属性(该属性肯定只适用于类,而不适用于特定实例)

我可以创建一个抽象布尔方法
isFooBar()
,子类可以实现该方法来指示属性是否存在:

public abstract class MyBaseClass {
  ...
  public abstract boolean isFooBar();
}
或者,我也可以使用标记接口
FooBarProperty
,并对接口执行
instanceof
检查:

public class MyConcreteClass extends MyBaseClass implements FooBarProperty {
   ...
}
或者我猜你甚至可以使用AmitD建议的注释:

@FooBarAnnotation
public class MyConcreteClass extends MyBaseClass {
   ...
}

每种方法的优缺点是什么,通常应该首选哪种方法?

Marker Interface没有任何方法。在您的情况下,接口有一个获取属性的方法,在此基础上,您应该使用接口。您可以简单地使用此接口来保存实现接口的类的具体实例,并可以调用与属性相关的方法


但是,在另一端,使用或标记标记和实例或层次结构,以便它符合某些功能(如持久性)的条件。

标记接口在类层次结构中继承,因此它们的功能有限(您不能为某些特定子类“删除”此标记接口),我不能推荐它们(Cloneable是一个很糟糕的例子)。问题是-您的属性真的绑定到对象的类而不是实例吗?如果是这样,注释会更好,因为它们不会向API中添加额外的方法,并且更易于维护-您只需添加/删除注释即可(对于checking方法,您必须检查所有子类,无论它们是否重写它)


编辑:在您的情况下,我会问自己一个问题:我的属性类似于“IsPersistent”(适用于给定类的所有实例)还是“IsVisible”(仅适用于某些实例)

您还可以在问题中添加另一个选项作为
注释
?我想说,抽象方法在面向对象方面更清晰。使用instanceof通常是设计缺陷的标记。注释是特定于类的-您可以将属性附加到类,但不能附加到实例。标记接口也是如此-您可以正在标记整个类,而不是单个实例。使用抽象方法方法,每个对象都可以决定返回哪个值。我刚刚读完重分解,但我仍然处于这种状态。我将选择选项1简单的代码更少。如果需要,将选择选项3动态和可扩展的,但需要更多的代码。Framework Design Guidelines,2nd,p.99f,提出了另外两点(尽管是针对.NET):1)检查注释比检查类型慢。2)有了接口,编译器可以强制类来实现标记。