英文:
Get subclass from super class constructor
问题
我有一个执行操作的 X 类。可以有多种类型的 X。通常我会为每种类型做一个子类,但是我程序中的一部分我无法更改,它使用 X 构造函数声明和实例化 X。除了构造函数的签名外,我对 X 有完全的控制权(构造函数被我无法更改的程序部分调用)。
我考虑为每种类型创建一个 Xcontroller,其中包含我想要重写的方法并存储在 X 中。某些方法需要使用 X 的 super 方法,除非我弄错了,我不能从另一个类调用它们。
示例代码:
class cantTouchThis {
public static void main(String[] args) {
// 不能更改这部分
X x = new X("必需的参数");
doThings(x);
}
private static void doThings(X x) {
// 使用 X 进行操作
}
}
enum Type {
A, B, C;
public static Type iKnowHowToGetTheTypeTrustMe() {
// 总是返回实例的正确类型
}
}
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) {
// 操作
}
}
我更愿意将不同类型作为它们自己的类(类 A 扩展 X,类 B 扩展 X,类 C 扩展 X)。但是我必须使用 cantTouchThis
中的代码,它总是声明一个 X 并使用 X 构造函数实例化。X 类中有大量的 switch 语句和许多实例变量,只用于特定类型,在其余时间无用。
是否有办法使 X 构造函数改变自己的类型,并成为它的子类之一?
英文:
I have an X class that does stuff. There can be multiple kinds of X. Usually I'd just do a subclass for each type, but there is a part of my program that I can't change that declares and instantiates an X with the X constructor. I have total control on X, except for the constructor signature. (which is called by the part of my program I can't change)
I thought about making an Xcontroller for each type that contains the methods I want to override and are stored in X. Some methods require the use of super methods of X and unless I'm mistaken, I can't call them from another class.
Example code:
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
}
}
I'd rather make the type their own classes (class A extends X, class B extends X, class C extends X).
But I have to use the code in cantTouchThis which always declares an X and instantiates with the X constructor.
The X class has a ton of switch cases, and a lot of instance variables used only for certain types and useless the rest of the time.
Is there a way to make the X constructor change it's own type and become one of it's subclasses ?
答案1
得分: 1
你可以使用工厂模式。(示例:https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/ServerSocketEx.java)
在ServerSocketEx中,有一个SocketRunnerFactory。SocketRunnerFactory是用于创建SocketRunner的接口。因此,每当ServerSocket接受新连接时,它都会从工厂获得一个新的SocketRunner。而且你可以创建自己的ServerRunnerFactory来处理Socket,以任何你想要的方式。
你会使用这个模式来创建X的子类。
英文:
You can use the factory pattern. (example: https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/ServerSocketEx.java)
In ServerSocketEx, there is a SocketRunnerFactory. SocketRunnerFactory is an interface for creating SocketRunners. So every time the ServerSocket accepts a new connection, it gets a new SocketRunner from the factory. And you can create your own ServerRunnerFactory to handle the Socket however you want
You'd use this pattern to created subclasses of X's.
答案2
得分: 1
你可以使用委托(delegate)。类似这样:
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;
// 以此类推...
}
}
public void a(Object one, Object two) {
delegate.a(one,two);
}
}
然后在 AX、BX、CX 中根据你的需要实现 a
方法。
英文:
You could use a delegate. Something like this:
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);
}
}
And then implement a in AX, BX, CX as you like.
答案3
得分: 0
以下是您要求的翻译内容:
所以似乎我无法按照我想要的方式更改构造函数(感谢 @JoakimDanielson)
我找到了一种使用控制器的方法:
如果我在 X 中创建一个名为 superA 的方法,只需调用 super 方法,它可以从控制器调用。
示例代码:
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;
// 依此类推...
}
}
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);
}
}
感谢您的帮助,如果有更清晰/更好的方法,请告诉我。
英文:
So it seem I can't change the constructor the way I want (thanks @JoakimDanielson)
I found a way to use controllers:
If I create a superA method in X that just call the super method, it can be called from the controller.
Exemple code:
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);
}
}
Thanks for your help, if there is a cleaner/better way please tell me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论