必要时如何垂头丧气?

How to downcast when it's necessary?

我在公司软件中遇到了一个令人沮丧的问题,我找不到解决方法。 (这是既定的事情,我无法改变整个构想)

我将尝试通过示例向您提供整个上下文:基本上,我们有 2 个软件组件,比方说 BrickHigh、BrickLow。 BrickLow 可以使用 BrickHigh 的所有内容,但 BrickHigh 看不到 Bricklow。

在 BrickHigh 中有一个 Animal class(许多属性)及其 DAO :

public class Animal .. {
 //attributes...
}

在 BrickLow 中,我创建了一个 Cat class(还有许多未映射的属性),它扩展了 Animal。

public class Cat extends Animal {
//attributes
}

我们打算做的是让每个映射属性都有一个超级 class(Animal)。但是我不能在我的应用程序中使用我的动物 class,因为它会因为整个应用程序使用 Cat.

而改变太多

但很明显,我无法在从 DAO 获取 Animal 后将其转换为 Cat,因为 Java 不允许,我需要 Animal 的所有信息。

因为我的 BrickHigh 看不到我的 BrickLow,所以没有像 Animal animal = new Cat(); 这样的东西。可能。

我的第一个想法是在 Cat 中创建一个将 Animal 作为参数的构造函数

public Cat(Animal a) {
 super(a);
}

但是我的 Animal 中的构造函数必须是什么 class?好像不行。

But what my constructor must be in my Animal class? It doesn't seem to work.

像这样:

   public Animal(Animal other) {
      this.field1 = other.field1;
      this.field2 = other.field2;
      // etc
   }

但是,我认为使用对象工厂模式可能会更好;即让你的 DAO class 接受一个参数,它是一个 factory 对象,可以创建 Animal 个实例。当您在使用 BrickLow API 的代码中使用 DAO(来自 BrickHigh)时,您可以使用生成 Cat 个实例而不是 Animal 个实例的工厂实例化 if。

我不确定我是否完全理解你的问题,但如果你想从 BrickHigh 的代码中创建某种动物的实例 class,但不了解 BrickLow,你可以使用工厂或 Class 对象,它们将由 DAO 的一个或多个属性标识。

例如:

public interface AnimalFactory {
    boolean canInstanciate(AnimalDAO dao);
    Animal instanciate(AnimalDAO dao);
}

您的 BrickHigh 将拥有一组工厂,并提供注册新工厂的机制。

例如:

public enum AnimalFactories implements AnimalFactory {
    INSTANCE;

    private List<AnimalFactory> factories = new ArrayList<>();


    public void registerFactory(AnimalFactory factory) {
        factories.add(factory);
    }

    @Override
    public boolean canInstanciate(AnimalDAO dao) {
        for (AnimalFactory fac: factories) {
            if (fac.canInstanciate(dao)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Animal instanciate(AnimalDAO dao) {
        for (AnimalFactory fac: factories) {
            if (fac.canInstanciate(dao)) {
                return fac.instanciate(dao);
            }
        }
        throw new InstanciationException("No factory for that animal");
    }
}