使用超类"protected final"方法来保留子类的公共代码



作为一个(迂滥调的)初级Java程序员,我想知道,将所有子类使用的共同代码块移动到父类中单独的受保护的 (final)方法是否是一个好做法?像填充具有共同值的列表或共同过滤算法等任务……也使用受保护的静态方法是好的吗?

class A {
    protected final List<String> getVariants() {...}
    protected final List<String> filterResults(List<String> variants) {...}
}
class B extends A {
    public List<String> doSomethingUsefull() {
        List<String> commonVariants = getVariants();
        ...
        return filterResults(commonVariants);
    }
}
class C extends A {
    public void doSomethingUsefull() {
        List<String> commonVariants = getVariants();
        ...
        return filterResults(commonVariants);
    }
    public void doMoreUsefullThings() {
        List<String> commonVariants = getVariants();
        ...
        return filterResults(commonVariants);
    }
}

如果你是一个Java初学者,或者你正在考虑这些事情,那么现在是阅读"类和接口"的好时机。《高效Java》一书中的一章。那里的信息会比你在这里得到的答案更彻底、更细致。

这是考虑混合final, protectedstatic关键字的一种方法:

  • OO纯粹主义者会建议您避免使用static,因为它破坏了OO范例。当然,使用final关键字也可以防止子类重写方法。在这方面,结果与static相同。
  • final应该更频繁地使用,并且与protected一起使用是一个好主意。见"有效java"条款17。
  • protectedstatic不经常一起使用。你将OO构造与破坏正常OO行为的构造混合在一起,所以这种组合是奇怪的。

这对我来说似乎是合理的-尽管您可能也想使A抽象。也考虑使用组合代替- BC 可以包含A,而不是子类化它?

首先,您不应该将扩展用于此目的,因为过多的扩展总是坏主意。

其次,你不重复代码是完全正确的,但是按照重复的代码部分进行分组并不是一个好的选择。更可取的方法是将现实世界中的意义按抽象层次进行分组。

最后但并非最不重要的是,当你有疑问:单独或不单独,扩展或组合,保护最终或仅保护,试着写单元测试到这个类,答案会很快出现

如果这些方法不依赖于某些类字段,我建议将它们移动到单独的静态类中。

最新更新