在抽象类中公开静态方法被认为是好还是坏的做法[关闭]
Posted
技术标签:
【中文标题】在抽象类中公开静态方法被认为是好还是坏的做法[关闭]【英文标题】:Is exposing static methods in abstract classes considered good or bad practice [closed] 【发布时间】:2020-02-07 22:57:32 【问题描述】:我最近遇到了一些代码,其中在 abstract
类中定义了 public static
方法。我想知道这是否被认为是好的做法或反模式?
我制作了一个简单的示例程序来说明我的意思。
public abstract class StaticMethodsInAbstractClassesStudy
public static int adder(int a, int b)
return a + b;
public class StaticMethodsInClassesStudy
public static void main(String [] args)
System.out.println(StaticMethodsInAbstractClassesStudy.adder(2, 3));
当您运行代码时,您会得到5
的结果,这证明我能够在abstract
类中运行代码。
我故意不将extends
添加到StaticMethodsInClassesStudy
以强调完全可以直接在abstract
类中运行代码而无需实例化扩展类。
我个人认为这是一种不好的做法,因为您将abstract
类用作普通类,从而绕过了abstract
类的intent。这些方法不应该保存在单独的“普通”java类中,例如实用类?
【问题讨论】:
如果您从不打算将StaticMethodsInAbstractClassesStudy
实例化(也就是说,StaticMethodsInAbstractClassesStudy
的实例没有用处),则没有理由将其抽象化。使用私有构造函数使其成为最终类。
请定义“好的做法”和“坏的做法”。这些只是意见。
这真的取决于所涉及的方法,静态通常被人们首先进入编程领域滥用作为字段/方法访问的创可贴。通常,只要静态方法以不会修改某些内部(和静态)状态的方式使用,通常是静态的就可以了。总的来说,这取决于你的设计
另一件要考虑的事情:static
方法不是继承的,因此不能被子类覆盖。如果您打算覆盖它,那么它不能是static
,如果您不希望它被覆盖,那么final
会比static
更明确地为您执行此操作。
当然你可以在抽象类中运行代码。你只是不能实例化它们。静态初始化程序将是演示它的另一种方式,无需子类化或以其他方式弄乱您的示例。
【参考方案1】:
我同意你的观点,abstract
类让我们想到在实例化之前不要使用的东西。
在抽象类中插入一些支持方法而不强制开发人员实现该类是允许且有用的。
您还可以在Interface
中放置静态方法,并且您可以在不实现该接口的情况下使用它们。
【讨论】:
【参考方案2】:这本身并不是一个坏习惯,除非抽象类实际上并不打算被子类化,而抽象只是为了防止实例化。仅提供静态实用程序的类的最佳做法是将其设为 final,并拥有一个私有构造函数。
【讨论】:
“仅提供静态实用程序的类的最佳实践是使其成为最终的,并拥有一个私有构造函数。” > 一个方便的方法是创建一个没有实例的枚举。 @bowmore 并且恕我直言,这与使用抽象类来防止实例化一样滥用(如果不是更多的话)。枚举应该具有枚举值。它有一个 valueOf() 方法、一个 values() 方法等,它们不应该是实用程序类的一部分。 好吧,我想说的是创建一个只提供静态实用程序的类,你已经把最佳实践扔到了窗外:) @bowmore 呵呵。不,拥有静态实用程序和工厂方法是很常见和正常的。参见 java.util.Collections、SwingUtilities、Guava 的 Maps、Lists、Sets 等。 被普遍使用并不代表最佳实践。工厂方法当然是静态方法的一个很好的用途,但我不明白为什么需要将这些方法分组到一个无法实例化的单独类中。其他类型的静态方法,位于不可实例化的类中,只是促进了强耦合。从本质上讲,它遇到了许多与单例相同的问题。此外,以Collections
为例,您会看到很多方法,如 max、reverse、rotate、shuffle 等,这些方法明显带有嫉妒的味道。 SwingUtilities 也是如此。以上是关于在抽象类中公开静态方法被认为是好还是坏的做法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
混合 Angular Material 和 Bootstrap。好的做法还是坏的做法?