Я бы сказал, что есть 2 варианта.Любой может не стесняться, поскольку этот вопрос интересен.
Используйте один файл для кода Java вместо пакетов
Идея состоит в том, что вы можете использовать одинJava-файл для объявления классов и API, доступных для Car.java (Engine и Battery).Классы, объявляющие понятия, скрытые от 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
Объедините использование абстрактных и защищенных модификаторов вместе с подпакетами
Идея состоит в том, что вы создаете публичные абстрактные классы, функциональность которых предоставляется защищенными методами.Например, AbstractBattery и AbstractEngine.Затем вы можете создать некоторые классы, которые действуют как «прокси», вы расширяете абстрактные классы частными реализациями пакета в пакете Car и переопределяете методы, которые вы хотите сделать доступными.Например, двигатель и аккумулятор.Автомобиль будет иметь доступ к переопределенным методам абстрактных классов.Другим побочным эффектом является то, что вы не можете иметь окончательные методы API в своих AbstractClasses.
Этот подход больше подходит для больших баз кода и направлен на то, чтобы скрыть функциональность и абстракции от непреднамеренного использования.Однако это требует дополнительной работы.Конечно, другие по-прежнему могут расширять 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();
}
}