假设我有 3 节课。一个类是超类,另外两个是从它继承的。如果我有一个超类的实例,并且我想知道两个子类中的哪一个,那么这个对象就是它的实例。
两种方法中的哪一种被认为是最佳实践:1)使用 instanceOf 或 getClass() 并进行比较,或 2)在超类上声明一个抽象方法并在子类上实现它以获得代表该类的枚举。
假设我有 3 节课。一个类是超类,另外两个是从它继承的。如果我有一个超类的实例,并且我想知道两个子类中的哪一个,那么这个对象就是它的实例。
两种方法中的哪一种被认为是最佳实践:1)使用 instanceOf 或 getClass() 并进行比较,或 2)在超类上声明一个抽象方法并在子类上实现它以获得代表该类的枚举。
在这种情况下,最佳实践是多态。在超类中创建一个抽象方法。子类将有义务提供具体的实现。不需要 instanceof 或 getClass。
您应该使用 instanceOf。使用 enum 的方法,您必须事先知道您将在稍后检查实例,并且必须为此准备类。所以我更喜欢instanceOf。
大多数时候,多态性是更好的答案。如果您必须询问哪个子类,那么当添加新的子类时,就有忘记在该问题中添加新的“if”部分的危险。
简短的回答:您可能正在尝试以最好避免的方式使用类对象或类名;通过避免它,您可能会使您的代码更清晰,更易于理解和扩展。
Long(er) 回答:在编写面向对象的软件代码时,特别是 Java,大量使用了(子类型)多态性原则。为了在您的问题的上下文中使其超级简化:如果您有一个 A 类的实例,并且 A 类由 B 和 C 扩展,您努力只将 A 视为“通用”A,使用它的公共方法和会员;如果你想为 B 和 C 做一些不同的事情,你可以为 A 上的这个动作编写一个方法 doSomething(),通过覆盖 A.doSomething()(A 的默认实现)在 B 和 C 中以不同的方式实现。
(正如@EvgeniyDorofeev 的回答中所建议的那样,如果没有默认操作,您可以将默认方法设为抽象;但 A 必须是抽象类。)
这有几个优点:
但它有时也受到批评,作为对面向对象方法的更普遍批评的一部分(例如,参见OOP Oversold的The Noun Shuffle)。
PS:有时您无法避免使用 getClass() (例如,用于准备包含类名的日志消息);OP 没有具体说明他/她面临的确切问题,所以很难说。无论如何,不要走上为类编写自己的枚举的道路;使用 getClass() (如果你真的需要它,你也可以从中获取类名)。此外,您可能会发现可以使用一个库来为您处理这些事情,因此您根本不必 getClass() (这就是日志记录的情况,我刚刚给出的示例。)
通常最好的做法是调用布尔函数 instanceOf(),这应该可以正常工作。
虽然我自己发现您的第二个解决方案更容易使用,但第一个被认为是良好的编程实践。