如何在必要时贬低?

时间:2017-07-06 12:07:34

标签: java downcast

我在公司软件中遇到了一个垂头丧气的问题,我无法找到解决方法。 (它已经落实到位,我不能改变整个概念)

我将尝试用一个例子给你整个上下文:基本上,我们有2个软件组件,让我们说BrickHigh,BrickLow。 BrickLow可以使用BrickHigh中的所有东西,但BrickHigh无法看到Bricklow。

在BrickHigh中有一个带有DAO的Animal类(几十个属性):

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

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

public class Cat extends Animal {
//attributes
}

打算做的是拥有一个包含每个映射属性的超类(Animal)。但我不能在我的应用程序中使用我的动物类,因为整个应用程序使用Cat会有太多变化。

但很明显,我从DAO那里获取它之后就无法将我的Animal投射到Cat,因为Java不允许它,我需要来自Animal的所有信息。

由于我的BrickHigh没有看到我的BrickLow,所以没有Animal animal = new Cat();可能的。

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

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

但是我的构造函数必须在我的Animal类中?它似乎不起作用。

2 个答案:

答案 0 :(得分:2)

  

但是我的构造函数必须在我的Animal类中?它似乎不起作用。

这样的事情:

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

但是,我认为使用Object Factory模式可能会更好;即让您的DAO类采用参数,该参数是可以创建Animal个实例的 factory 对象。在使用BrickLow API的代码中使用DAO(来自BrickHigh)时,可以使用生成Cat个实例而非Animal实例的工厂实例化。

答案 1 :(得分:1)

我不确定我完全理解你的问题,但是如果你想在BrickHigh的代码中创建一些动物类的实例,但是不知道BrickLow,你可以使用工厂,或者由DAO的一个或多个属性标识的Class对象。

例如:

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");
    }
}