在最后一个构造函数结束后调用方法

时间:2014-11-02 22:51:10

标签: java constructor

我对可能无法做到的事情有疑问,但值得一试。

我有这些课程:

Class A {
    private int x = 0;

    public A() {
        afterCreate();
    }

    public void afterCreate() {
        x = 10;
    }

    public int getX() { 
        return x; 
    }
}

Class B extends A {
    public B() {
        super();
        //Do something
        afterCreate();
    }

    @Override
    public void afterCreate() {
        x = 20;
    }
}

Class C extends B {
    public C() {
        super();
        //Do something
        afterCreate();
    }

    @Override
    public void afterCreate() {
        x = 30;
    }
}

如您所见,我需要始终在构造函数结束时自动调用afterCreate()。但是,如果我只是在每个构造函数中调用afterCreate(),您可以看到对于从类C创建的对象,我们将调用方法afterCreate()三次(每个构造函数一个) - - 前两个电话无用。

另外,我无法在第一个构造函数中调用afterCreate(),因为afterCreate()必须在最后一个构造函数之后执行。

Class A {
    public A() {
        //Do something
        afterCreate();
    }
}

Class B extends A {
    public B() {
        super();
        //Doing something that I missed to process in afterCreate()!
    }
}

Class C extends B {
    public C() {
        super();
        //Doing something that I missed to process in afterCreate()!
    }
}

显然,我不能在类C的构造函数中调用afterCreate(),因为如果我从类A或B创建对象,则不会调用该方法。

有没有办法可以在LAST构造函数结束时自动调用afterCreate()

现在,想一想这个问题,也许如果我能检测到构造函数是在超类中调用的,我可以检测出是否可以调用该方法。

Class A {
    public A() {
        //Do something
        if(thisIsNotCalledAsASuperClass()) afterCreate();
    }
}

Class B extends A {
    public B() {
        super();
        //Do something
        if(thisIsNotCalledAsASuperClass()) afterCreate();
    }
}

Class C extends B {
    public C() {
        super();
        //Do something
        if(thisIsNotCalledAsASuperClass()) afterCreate();
    }
}

//Class D extends C {
//etc.

我不知道......你怎么看?

1 个答案:

答案 0 :(得分:6)

这是一个坏主意。它通常被认为是构造函数的反模式,用于调用基于子类更改行为的方法。

如果您确实需要此功能,我建议在每个类上使用工厂方法,并阻止对构造函数的直接访问。问题是您正在为未完全初始化的实例调用可覆盖的方法。

Class A {
    private A() {
        //Do something
    }
    public static A newA() {
        A a = new A();
        a.afterCreate();
        return a;
    }
}

Class B extends A {
    private B() {
        super();
    }
    public static B newB() {
        B b = new B();
        b.afterCreate();
        return b;
    }
}

Class C extends B {
    private C() {
        super();
        //Do something
    }
    public static C newC() {
        C c = new C();
        c.afterCreate();
        return c;
    }
}