繁体   English   中英

从超级 class 构造函数获取子类

[英]Get subclass from super class constructor

我有一个 X class 可以做事。 可以有多种 X。通常我只为每种类型创建一个子类,但是我无法更改程序的一部分,它使用 X 构造函数声明和实例化 X。 除了构造函数签名之外,我对 X 有完全的控制权。 (由我无法更改的程序部分调用)

我考虑为每种类型创建一个 Xcontroller,其中包含我想要覆盖的方法并存储在 X 中。有些方法需要使用 X 的超级方法,除非我弄错了,否则我不能从另一个 class 调用它们。

示例代码:

class cantTouchThis{
    public static void main(String[] args){
        // Can't change this
        X x = new X("obligatory parameter");
        doThings(x);
    }

    private static void doThings(X x){
        // do stuff with X
    }
}

enum Type{
    A, B, C;
    public static Type iKnowHowToGetTheTypeTrustMe(){
        // Always return the good type for the instance
    }
}

class X extends SuperClass {
    public X(String string){
        Type type = Type.iKnowHowToGetTheTypeTrustMe();
    }

    public void a(Object one, Object two){
        switch(type){
            case A:
                super.a(one, two);
                return;
            case B:
                doOtherThings(one, two);
                return;
            case C:
                super.a(two, one);
                return;
        }
    }

    private void doOtherThigns(Object one, Object two){
        // stuff
    }
}

我宁愿将类型设为自己的类(A 类扩展 X,class B 扩展 X,class C 扩展 X)。 但是我必须使用 cantTouchThis 中的代码,它总是声明一个 X 并使用 X 构造函数进行实例化。 X class 有大量的开关案例,以及许多仅用于某些类型的实例变量,而当时的 rest 无用。

有没有办法让 X 构造函数改变它自己的类型并成为它的子类之一?

您可以使用工厂模式。 (例如: https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/ServerSocketEx.java

在 ServerSocketEx 中,有一个 SocketRunnerFactory。 SocketRunnerFactory 是一个用于创建 SocketRunner 的接口。 所以每次 ServerSocket 接受一个新的连接时,它都会从工厂获取一个新的 SocketRunner。 您可以创建自己的 ServerRunnerFactory 来处理您想要的 Socket

您将使用此模式来创建 X 的子类。

您可以使用委托。 像这样的东西:

class X extends SuperClass {

    private final SuperClass delegate;

    public X(String string){
        Type type = Type.iKnowHowToGetTheTypeTrustMe();
        switch(type) {
            case A:
                delegate = new AX(string);
                break;
            case B:
                delegate = new BX(string);
                break;
            // and so on...
        }
    }

    public void a(Object one, Object two) {
        delegate.a(one,two);
    }
}

然后在 AX, BX, CX 中实现一个你喜欢的。

所以看来我无法按照我想要的方式更改构造函数(感谢@JoakimDanielson)我找到了一种使用控制器的方法:

如果我在 X 中创建一个只调用 super 方法的 superA 方法,则可以从 controller 调用它。

示例代码:

class X extends SuperClass {
    private final Controller controller;

    public X(String string){
        Type type = iKnowHowToGetTheTypeTrustMe();
        switch(type) {
            case A:
                controller = new AX(this);
                break;
            case B:
                controller = new BX(this);
                break;
            // and so on...
        }
    }

    public void superA(Object one, Object two){
        super.a(one, two);
    }

    public void a(Object one, Object two){
        controller.a(one, two);
    }
}

class Controller {
    private X x;
    public Controller(X x) {this.x = x;}
    public getX(){...}
}

class AX extends Controller {
    public void a(Object one, Object two) {
        getX().superA(one, two);
    }
}

感谢您的帮助,如果有更清洁/更好的方法,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM