java - 从基类设置派生类成员

标签 java design-patterns

这是一个人为的示例:(实际代码中使用的命名方案太困惑了)

我有一个类Father,它扩展了Grandfather,它是第三方库的一部分,无法更改。我还有一些延伸父亲的类(class);以儿子为例。祖父有一个如下所示的构造函数:

public Grandfather(String name) {...}

这个构造函数中实际发生的事情并不重要。重要的是,无论它做什么,所有派生类也必须完成,因此调用 super(String)是每个派生类构造函数的强制第一行。这里的含义是,Grandfather 的所有后代的构造函数,无论距离多远,都必须始终调用 super (或调用 super 的链式构造函数)作为其第一行。

在我的父亲实现中,我有一个方法 configure(String xml)它解析 xml 文件并使用反射来设置实例内的各种参数。这些参数有些在祖父中,有些在父亲中,有些甚至可能在儿子中。每次实例化从 Father 派生的类时,Configure 都需要运行。我最初的想法是简单地添加对 configure(String) 的调用像这样的我父亲的构造函数:

public Father(String name, String xml) extends Grandfather {
  super(name);
  configure(xml);
}

这对于 Granfather 和 Father 实例化效果很好,但在 Son 实例化时会崩溃,其原因与从构造函数中调用可重写方法通常会崩溃的原因基本相同。考虑以下 Son 实现:

public class Son extends Father {
  private String occupation = "unknown";

  public Son(String name, String xml) {
    super(name, xml);
  }
}

发生的情况是这样的:

  1. 使用new Son(String, String)实例化一个新的Son .
  2. Son(String, String)内调用super(String, String)是制成的,即。 Father(String, String) .
  3. Father(String, String)configure(String)被称为。
  4. configure(String)找到 <occupation>元素并使用反射调用 setOccupation("Coal Miner") .
  5. Father(String, String)退出并执行返回到 Son(String, String) .
  6. 在 Son 退出之前,所有提供默认值的成员都会被设置(这是内联在 Java 构造函数的末尾)
  7. 占用被内联覆盖并设置为“未知”。

我想避免重复调用configure(String)因为它是一个潜在昂贵的操作,所以添加对 configure(String) 的调用在每个构造函数的末尾都是out。 (这将导致 configure(String) 对于 Son 实例被调用两次,对于第 n 代后代被调用 n 次。

我还想避免手动调用 configure(String)实例化父亲或其任何后代后:

Son s = new Son(...);
s.configure(...);

工厂方法在这里可以很好地工作,但由于祖父实例的使用方式,这是不可能的。长话短说,我几乎从来都不是实例化这些类的人,并且对实例化代码的访问权限为零。

或者换句话说,执行以下操作:

Father f = new Father(...);

会导致configure(...)被父构造函数调用一次,同时:

Son s = new Son(...);

会导致configure(...)被 Son 构造函数调用一次。

考虑到这些限制,有人能想出一种方法来实现我的目标吗?还是我完蛋了?

最佳答案

从您的声明来看,您似乎并不真正反对在 ctor 末尾显式调用configure。

那么,这种扭曲可以接受吗?

class GrandFather {
  GrandFather(String name, boolean configure) {
    // some init
    if (configure) {
      configure(name);
    }
  }

  GrandFather(String name) {
    this(name, true);
  }
}

class Father {
  Father(String name, boolean configure) {
    super(name, false);

    // some init
    if (configure) {
      configure(name);
    }
  }

  Father(String name) {
    this(name, true);
  }
}

class Son {
  Son(String name, boolean configure) {
    super(name, false);

    // some init
    if (configure) {
      configure(name);
    }
  }

  Son(String name) {
    this(name, true);
  }
}

这个想法是,每个继承的类在其构造函数中显式调用配置,但它要求父类不要配置自己。

关于java - 从基类设置派生类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12774853/

相关文章:

sql - 是否有用于减少重复连接表数据的数据库设计模式名称?

design-patterns - 您认为哪种设计模式最重要?

java - POI 朗读Word文档中的句子

java - 使用私有(private)构造函数来防止类的实例化?

design-patterns - 捕获所有异常并将它们作为特定类型的异常在分类方面重新抛出是一种好的做法吗?

c# - 网站中的设置类

java - 具有静态工厂方法或构造函数的工厂模式

java - 如何使在我的应用程序中运行 Activiti Modeller 时,定时器之后的任务和脚本任务服务不会导致错误?

java - Java 中 <T> 和 <T extends Object> 有什么区别?

java - 报警管理器运行