您确实在使用模板模式。您可以做两件事来向外部用户“隐藏”详细信息:
1) 了解您的access modifiers:
Access Levels
Modifier | Class | Package | Subclass | World |
--------------------------------------------------
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
no modifier | Y | Y | N | N |
private | Y | N | N | N |
很少有坚定的黑客通过反射来克服这些保护措施,这些可以防止临时编码人员意外调用最好避开他们的方法。编码人员会欣赏这一点。没有人愿意使用杂乱无章的 API。
目前b.doWork() 是protected。所以它只会在你的main() 中可见,如果你的main() 在类A(不是),子类B(不是),或者在同一个包中(不清楚,你没有发布有关您的代码所在包的任何线索)。
这就引出了一个问题,你想保护谁不看到b.doWork()?如果您正在创建的包是只有您正在开发的东西,它可能不会那么糟糕。如果很多人在这个包中跺脚,与许多其他类混在一起,那么他们不太可能对类A 和B 非常熟悉。在这种情况下,您不希望所有东西都挂在每个人都可以看到的地方。在这里只允许类和子类访问会很好。但是没有修饰符允许子类访问而不允许包访问。只要你继承protected 就是你能做的最好的。考虑到这一点,不要去创建包含大量类的包。保持包装紧凑和专注。这样一来,大多数人都会在看起来不错且简单的包之外工作。
简而言之,如果您希望阻止 main() 调用 b.doWork(),请将 main() 放入不同的包中。
package some.other.package
public final class Main {
...
}
2) 下一条建议的价值将很难用您当前的代码来理解,因为它是关于解决只有在扩展您的代码时才会出现的问题。但这确实与保护人们不看到b.doWork()之类的东西的想法密切相关
What does "program to interfaces, not implementations" mean?
在您的代码中,这意味着如果 main 看起来像这样会更好:
public static void main(String[] args) {
A someALikeThingy = new B(); // <-- note use of type A
someALikeThingy.work(); //The name is silly but shows we've forgotten about B
//and know it isn't really just an A :)
}
为什么?使用A 类型与B 类型有什么关系? A 更接近于成为一个接口。请注意,这里我不仅仅指使用关键字interface 时得到的结果。我的意思是B 类型是A 类型的具体实现,如果我不是绝对要针对B 编写代码,我真的宁愿不要,因为谁知道A 以外的东西B 有什么奇怪的东西。这在这里很难理解,因为 main 中的代码又短又甜。此外,A 和B 的公共接口 并没有什么不同。他们都只有一个公共方法work()。想象一下main() 又长又复杂,想象一下B 有各种各样的非A 方法挂在它上面。现在假设您需要创建一个您希望 main 处理的类 C。看到 main 被喂了一个 B ,就 main 中的每一行都知道 B 只是一些简单的 A 之类的东西,这不是很令人欣慰吗。除了new 之后的部分之外,这可能是真的,并且可以让您免于对main() 做任何事情,而是更新new。确实,这难道不是为什么使用强类型语言有时会很好吗?
如果您认为即使在使用B() 更新new 之后的那部分工作量太大,您并不孤单。正是这种特别的小痴迷给了我们dependency injection movement,它催生了一堆框架,这些框架实际上更多的是关于自动化对象构造,而不是任何构造函数都可以让你做的简单注入。
更新:
我从您的 cmets 看到您不愿意创建小而紧的包。在这种情况下,考虑放弃基于继承的模板模式,转而采用基于组合的策略模式。你仍然得到多态性。它只是不会免费发生。更多的代码编写和间接。但是即使在运行时您也可以更改状态。
这似乎违反直觉,因为现在doWork() 必须是公开的。那是一种什么样的保护?好吧,现在您可以将B 完全隐藏在AHandler 后面甚至内部。这是一些对人类友好的外观类,它包含曾经是您的模板代码但只公开work()。 A 可以只是一个interface,所以AHandler 仍然不知道它有一个B。这种方法在依赖注入人群中很受欢迎,但肯定没有普遍吸引力。有些人每次都盲目地这样做,这让很多人感到烦恼。你可以在这里读更多关于它的内容:
Prefer composition over inheritance?