Java:子类构造函数完成后的后处理

发布于 2024-11-05 07:45:00 字数 456 浏览 1 评论 0原文

我想为一组类定义一些常见的构建后行为。当不同类中有共享行为时,Java 会告诉我们将它们提取到父类中。

从概念上讲,我们是说,对于这种类型的对象(及其子类),在构造后进行一些后处理;

实际上,这很难做到。显然不能将其放在父类构造函数中,因为父类构造函数是在子类构造函数之前调用的。我可以在父类中编写一个 postInit() 方法,并要求所有子类将其作为构造函数中的最后一个语句调用,但它看起来不太干净,因为没有办法强制执行它,而且人们确实会忘记。

是否有一些我不知道的语言结构可以解决我的问题?

谢谢,

请提供更多有关要求的背景信息。下面的许多答案(我已经投票)建议的工厂方法等都是好主意,但我真的没有那么奢侈。实际情况是这样的,我有这个父类,它扩展了几十个子类,这些子类又被用在很多其他地方。因此,重新设计这些子类的使用方式是不可能的,并且更改所有子类也是有可能的。理想情况下,我只需要更改父类,这就是我所要求的。

I want to define some common post-construction behavior for a group of classes. When you have shared behaviors in different classes, Java tells us to extract them out into a parent class.

Conceptually, it makes sense, we're saying, for objects of this type (and its subclasses), do some post-processing after it's constructed;

Practically, it's hard to do. You obviously can't put it in the parent class constructor because parent constructor is called before the subclass constructor. I could write a postInit() method in the parent class and require all subclasses to call it as their last statement in their constructors, but it doesn't seem very clean, as there's no way to enforce it, and people do forget.

Is there maybe some language construct that I'm not aware of that may solve my problem?

Thanks

Just a little more background on the requirement. Factory methods etc. that are suggested by many of the answers (which I've upvoted) below are all good ideas, but I don't really have that luxury. The actual situation is this, I have this parent class, which is extended by a couple of dozen subclasses, which are in turn used in many other places. So redesign how these subclasses are used is out of the question, and changing all subclasses is borderline possible. Ideally, I just need to change the parent class, so that's what I'm asking.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雄赳赳气昂昂 2024-11-12 07:45:00

如果出于实用原因无法使用工厂方法,我能想到的最佳解决方案是在根类中创建一个受保护的最终方法来进行后处理,并添加对每个叶类的方法;例如,

public abstract class Root {
    ...
    protected final void finishInit() {
        // Do post-processing
    }
}

public abstract class Intermediate {
    ...
    protected Intermediate(...) {
        super(...);
        ...
        // don't call finishInit();
    }
    ...
}

public class Leaf {
    ...
    public Leaf(...) {
       super(...);
       ...
       finishInit();
    }
    ...
}

如果 Intermediate 不是 abstract,那么您需要一个单独的公共构造函数来创建在最后调用 finishInit() 的实例。


这一切都有点笨拙,但如果您不能/不会重构代码以使用工厂方法,这就是您必须付出的代价。

If you can't use a factory method for pragmatic reasons, the best solution I can think of is to create a protected final method in the root class that does the post processing, and add a call to the method to each and every leaf class; e.g.

public abstract class Root {
    ...
    protected final void finishInit() {
        // Do post-processing
    }
}

public abstract class Intermediate {
    ...
    protected Intermediate(...) {
        super(...);
        ...
        // don't call finishInit();
    }
    ...
}

public class Leaf {
    ...
    public Leaf(...) {
       super(...);
       ...
       finishInit();
    }
    ...
}

If Intermediate is not abstract then you need a separate public constructor to create instances that calls finishInit() at the end.


It's all a bit clumsy, but that's the penalty you have to pay if you can't/won't refactor your code to use factory methods.

晚风撩人 2024-11-12 07:45:00

一种解决方案是没有任何公共角色。您可以使用工厂方法在将对象返回给调用者之前完成初始化。

One solution is to not have any public ctor. You can have a factory method that finishes the initialization before returning the object to the caller.

嘿嘿嘿 2024-11-12 07:45:00

嗯 - 最简单的解决方案是在 IDE 中为该类层次结构添加一个模板。

您是否考虑过您的设计以及如何更改它?
也许您需要某种设计模式,例如工厂方法、抽象工厂、构建器?

Well - the most simple solution is to add a template for this hierarchy of classes in the IDE.

Did you think about your design and how it can be changed?
May be you need some kind of design pattern, like Factory Method, Abstract Factory, Builder ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文