繁体   English   中英

标记界面与空抽象类

[英]Marker interface vs empty abstract class

我在使用标记接口或空抽象类之间做出决定时遇到困难。

我有两个类BrokerResponseNotification ,它们没有结构相似性。 连接它们的唯一方法是需要订阅。

void register(Receivable receivable, BrokerObserver observer)

我不喜欢使用Marker Interface ,因为它违反了Interface的基本定义。 另一方面,使用abstract super类会让我感到不舒服,因为这两个类彼此没有关系。

在这种情况下,通常更可取的方法是什么?为什么?

编辑1

我忘了提到, BrokerResponse本身就是一个抽象类,它有几个子类来确定各自的类型。

抽象类与标记接口:

标记界面没有任何问题,并且有一些用例。 选择这两者之间,标记界面具有更大的灵活性。

如果您确实要定义类型,请使用接口。

抽象类的目的是提供一个适当的超类,其他类可以从中继承并共享一个共同的设计 - 您的类没有共同的设计,也没有什么可以共享。 此外,如果你将来需要为他们添加一个真正不同的父母,你会把它们都粘在一些有限的设计上并且不会那么灵活。

抽象类的用例列表:

  • 在几个密切相关的类之间共享代码。

  • 扩展抽象类的类具有许多常用方法或字段,或者需要除公共之外的访问修饰符(例如protected和private)。

  • 声明非静态或非最终字段,使您能够定义可以访问和修改它们所属对象的状态的方法。

接口用例:

  • 不相关的类将实现您的接口。

  • 指定特定数据类型的行为,而不考虑谁实现其行为。

  • 多重遗产的优势。

所有列出的参数都是用于接口的。 由于BrokerResponse本身就是抽象的并且拥有自己的层次结构,因此这些类没有共同点的事实更加强大。

作为替代方案,您可以使用标记注释。 我会考虑坚持这两种方法中的一种而不是抽象类。

标记界面与标记注释:

根据Joshua Bloch的' Effective java ':

标记接口与标记注释相比具有两个优点。 首先,标记接口定义由标记类的实例实现的类型; 标记注释没有。 如果使用标记注释,则此类型的存在允许您在编译时捕获错误,直到运行时才能捕获这些错误。 标记接口相对于标记注释的另一个优点是它们可以更精确地定位。

什么时候应该使用标记注释?

如果标记适用于除类或接口之外的任何程序元素,则必须使用注释,因为只能使用类和接口来实现或扩展接口。

什么时候应该使用标记界面?

问问自己这个问题, 我想写一个或多个只接受具有此标记的对象的方法吗? 如果是这样,您应该使用标记接口而不是注释。 这将使您可以将接口用作相关方法的参数类型,这将带来编译时类型检查的真正好处。

摘要:

如果要定义一个没有与之关联的新方法的类型,则可以使用标记接口。

如果要标记类和接口以外的程序元素,以便将来可以向标记添加更多信息,或者将标记放入已经大量使用注释类型的框架中,那么标记注释是正确的选择。

在这种情况下使用空抽象类没有任何意义,因为Java没有多重继承。 使您的类实现一些标记接口不会改变您的类层次结构,它只是用一些额外的元数据标记您的类。

如果已经标记为Subscribable类也应该是Writable 如果使用空的抽象类,则需要重新设计整个层次结构。 使用标记接口,将Writable添加到实现列表就很容易了。

注释它们怎么样? 你得到的答案是,如果你必须选择,使用标记界面是这里的方法,但根据你可能需要做的事情使用注释会更清晰。

事实上,你说你需要让它们以某种方式“相同”谈论一个调用instanceof并根据它做一些事情。 同样的事情可以通过isAnnotationPresent等来实现。

但是,如果你添加一个标记界面,那么如何使它不是一个标记界面 - 只有你需要测试有限数量的类? MyInterface {boolean isSubscribable();}一些东西MyInterface {boolean isSubscribable();}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM