我会说有 2 个选项。任何人都可以随意参与,因为这个问题很有趣。
对 java 代码使用单个文件而不是包
这个想法是,您可以使用单个 java 文件来声明 Car.java(引擎和电池)可用的类和 API。声明对 Car 隐藏的概念的类(Spark、Belt、BatteryCell)应该是私有的和静态的,这样它们就不会与声明的类有隐式链接。
这种方法可以扩展,但需要更多的工作。这在一定程度上也是有帮助的,它不适合大型代码库,也不适合将来规模庞大的代码库。
org.automobile
|- Car
|- Engine.java <-- how to make this only available to Car
|- Engine.java-Spark <--private static class in File Engine.java
|- Engine.java-Belt <--private static class in File Engine.java
|- Battery.java <-- package private class
\- Battery.java - BatteryCell <--private static class in File Battery.java
将 abstract 和 protected 修饰符与子包结合使用
这个想法是您创建公共抽象类,其功能由受保护的方法公开。例如 AbstractBattery 和 AbstractEngine。
然后,您可以创建一些充当“代理”的类,使用 Car 包中的包私有实现扩展抽象类,并覆盖您想要提供的方法。例如发动机和电池。 Car 将有权访问抽象类的重写方法。另一个副作用是您的 AbstractClasses 中不能有最终的 API 方法。
这种方法更适合大型代码库,旨在隐藏功能和抽象以防止意外使用。但是,它需要更多的工作。
当然,其他人仍然可以扩展 AbstractBattery 和 AbstractEngine 并使用它们。
org.automobile
|- Car
|- Engine <-- extends AbstractEngine, is package private, overrides methods that Car needs to access
|- Battery <-- extends AbstractBattery,is package private, overrides methods that Car needs to access
|- drive.AbstractEngine <-- Public abstract class with no public methods, methods that are needed by Engine and Car are protected.
|- drive.Spark <-package private
|- drive.Belt <-package private
|- electric.AbstractBattery <--Public abstract class with no public methods, methods that are needed by Battery and Car are protected.
\- electric.BatteryCell <-package private
这是一个示例:
org.automobile.engine.AbstractEngine
package org.automobile.engine;
public abstract class AbstractEngine {
protected void startEngine(){
System.out.println("Zoom Zooomm Zoommm");
}
}
org.automobile.Engine
package org.automobile;
import org.automobile.engine.AbstractEngine;
final class Engine extends AbstractEngine {
@Override
protected void startEngine(){
super.startEngine();
}
}