【问题标题】:Dynamic constructor calling in java?在java中调用动态构造函数?
【发布时间】:2013-10-24 20:05:11
【问题描述】:

假设我有 4 个班级:ABSASB 其中B extends ASB extends SA

A 类具有以下构造函数:

private SA a;
public A() {
   a = new SA();
}

很明显,当我为 B 类调用构造函数时,并且因为 B extends AA 的构造函数也被调用。但在这种情况下,我想 A 的构造函数执行 a = new SB(); 而不是 a = new SA();

有没有一种简单的方法可以做到这一点 更改AB 的公共接口?

【问题讨论】:

  • 依赖注入! 不改变 A 和 B 的公共接口?不是真的。
  • @SotiriosDelimanolis 好的,如果您可以更改AB 的公共接口,您会怎么做?什么是最简单的方法(更改较少)?
  • 使A 的构造函数接受SA 参数。
  • 为什么一定要调用A的构造函数?只有在 B 的构造函数中调用 super 时才会发生这种情况。
  • @thatidiotguy Errr... No. JLS §8.8.7: 如果构造函数主体不是以显式构造函数调用开始并且被声明的构造函数不是原始类 Object 的一部分,那么构造函数体隐式地以超类构造函数调用“super();”开始

标签: java inheritance subtyping


【解决方案1】:

只要有一个public 构造函数和一个protected 构造函数:

private SA a;
public A() {
   this(new SA());
}
protected A(final SA a) {
   this.a = a;
}

然后在B:

public B() {
   super(new SB());
}

【讨论】:

  • 如果 2 个类在不同的包中怎么办。你不能做super(new SB());。因为A(final SA a) 受到保护
  • @foobar 不,protected 的全部意义在于它可以被另一个包中的子类访问。看看this
【解决方案2】:

是的。例如:

public A(YourEnum en) {
    if (en == YourEnum.SA){
        a = new SA();
    } else {
        a = new SB();
    }
}

另外,取决于你真正需要什么,可以通过重载构造函数来完成

public A(){
    a = new SA();
}

public A(YourObjectYouNeed dataNeededForAnotherConstructor){
    //doing initialization stuff
    a = new SB();
}

【讨论】:

  • 这看起来不太容易维护。如果我现在添加一个扩展AC 并且我想传入一个SC 怎么办?突然违反了 OCP。
  • 您正在添加一个全新的依赖项,而不是删除一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 2015-08-03
  • 2013-03-06
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
相关资源
最近更新 更多