java - 运行抽象构造函数,然后转换为子类

标签 java inheritance casting constructor

是否可以在一个方法中调用抽象构造函数,然后将其传递给其他一些方法,每个方法都会将新对象转换为特定的子类?也就是说,

public AbstractClass createNewAbstractClass() {
    //do lots of checks that are the same for each sub class,
    //including geting and checking each variable,
    //and an exception thrown by the constructor.
    AbstractClass abstractClassObject = new AbstractClass(var1, ...);
    return abstractClassObject;
}

public SubClassOne createSubClassOneObject() {
    SubClassOne subClassOneObject = (SubClassOne)createNewAbstractClass(var1,..);
    return subClassOneObject;
}

public SubClassTwo createSubClassTwoObject() { ...

解决这个问题的一种方法是获取并检查一个方法中的所有变量,然后将它们返回到一个数组中,以便方法 createSubClassNObject() 可以在正确的构造函数中使用它们,但这看起来很困惑,这意味着每个创建方法都必须以相同的方式检查相同的异常并对其执行相同的操作,这听起来正是您应该尝试外包给另一个方法的情况!

从实际的角度来看,我很感兴趣 - 我希望我的代码整洁且可读 - 但也从理论的角度来看 - 这实际上可能吗?那么即使答案是否定的,您能解释一下原因吗?

最佳答案

这有几个问题:

  • 抽象类无法实例化;抽象类的构造函数只能在子类的构造函数中调用。
  • 即使父类不是抽象类,(SubClassOne) 转换也会失败,因为我们实际上拥有的是 AbstractClass 类型的实例,而不是 类型的实例SubClassOne 被键入为 AbstractClass

不幸的是,返回 SubClassOne 的方法需要调用 SubClassOne 构造函数,该构造函数可能采用与 AbstractClass 相同的参数,并且只需使用 super 调用进行委托(delegate)即可。

我认为没有任何简单的方法可以在每个工厂方法中复制一些异常处理代码;构造函数不能很好地处理多态性。您可以有一个返回 AbstractClass 的中央构造函数,但它需要一个参数(枚举、Class 等)来告诉它要调用哪个子类构造函数。

abstract class Cow {
  Cow() throws Exception {
    ... // possible exceptions
  }
}

class FatCow extends Cow {
  FatCow() throws Exception {
    super();
    ...
  }
}

class GreenCow extends Cow {
  GreenCow() throws Exception {
    super();
    ...
  }
}

enum CowType {
  FAT_COW, GREEN_COW;
}

class CowMachine {
  static Cow makeCow(CowType type) {
    try {
      switch (type) {
        case FAT_COW:
          return new FatCow();
        case GREEN_COW:
          return new GreenCow();
        default:
          throw new IllegalArgumentException();
      }
    } catch (Exception e) {
      ...
      return null;
    }
  }

  static Cow makeFatCow() {
    return (FatCow) makeCow(CowType.FAT_COW);
  }

  static Cow makeGreenCow() {
    return (GreenCow) makeCow(CowType.GREEN_COW);
  }
}

如果您不需要大的 switch 语句,您可以接受 Class 对象并调用 newInstance,尽管这会比较慢。

关于java - 运行抽象构造函数,然后转换为子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8935722/

相关文章:

c - 如何将 ANSI-C 从 unsigned int * 转换为 char *?

c - 从 int 间接转换为 int *

java - 无法导入 com.google.maps.android :android-maps-utils via gradle

java - 当程序在VMWare中运行时,Socket的IP

java - 将 jacoco.exec 文件加载到 Sonar 中以进行多模块项目

mysql - 关于可空外键和规范化的数据库设计问题

python - 如何从父类扩展列表?

java - 如何从 Groovy 的 CliBuilder 获取正在运行的命令(或 jar、脚本)的名称?

java - 使用父类(super class)/子类引用引用新对象 JAVA

java - 在 Java 中向上转型