在任何派生类的构造函数之后运行方法 [英] Running a method after the constructor of any derived class

查看:128
本文介绍了在任何派生类的构造函数之后运行方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个Java类

Let's say I have a Java class

abstract class Base {
    abstract void init();
    ...
}

我知道每个派生类都必须在构造之后调用 init()。当然,我可以简单地在派生类的构造函数中调用它:

and I know every derived class will have to call init() after it's constructed. I could, of course, simply call it in the derived classes' constructors:

class Derived1 extends Base {
    Derived1() {
        ...
        init();
    }
}

class Derived2 extends Base {
    Derived2() {
        ...
        init();
    }
}

但这打破了不要重复自己的原则非常糟糕(并且会有许多 Base 的子类)。当然, init()调用不能进入 Base()构造函数,因为它将被执行太早了。

but this breaks "don't repeat yourself" principle rather badly (and there are going to be many subclasses of Base). Of course, the init() call can't go into the Base() constructor, since it would be executed too early.

任何想法如何绕过这个问题?我也很高兴看到Scala解决方案。

Any ideas how to bypass this problem? I would be quite happy to see a Scala solution, too.

更新:这是工厂方法方法的通用版本:

UPDATE: Here is a generic version of the Factory Method approach:

interface Maker<T extends Base> {
    T make();
}

class Base {
    ...
    static <T extends Base> T makeAndInit(Maker<T> maker) {
        T result = maker.make();
        result.init();
        return result;
    }
}

更新2:这个问题基本上是你好吗?使用模板方法为构造函数?答案似乎是,你可以,但这是一个坏主意。所以我可以改为使用模板工厂(模板方法+抽象工厂)。

UPDATE 2: This question is basically "how do you use Template Method for constructors"? And the answer seems to be, "You can, but it's a bad idea". So I can do a Template Factory (Template Method + Abstract Factory) instead.

推荐答案

中会发生什么的init()?更好的设计可能会完全消除该方法,或者至少放松它在子类的构造函数之后执行的要求。确保 init()在构造函数完成之前不会使构造中的对象对任何其他线程可见,因为这会产生并发错误。

What happens in init()? It's likely that a better design could eliminate the method altogether, or at least relax the requirement that it execute after the sub-class' constructor. Be certain that init() does not make the object under construction visible to any other threads before the constructor completes, because that creates concurrency bugs.

作为(丑陋的)替代方案,抽象方法可以由子类实现为伪构造函数:

As an (ugly) alternative, an abstract method could be implemented by sub-classes as a pseudo-constructor:

abstract class Base {
  Base() {
    ctor();
    init();
  }
  abstract void ctor();
  abstract void init();
}

这篇关于在任何派生类的构造函数之后运行方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆