Java 正在发送类型为object而不是字符串多态性的对象

Java 正在发送类型为object而不是字符串多态性的对象,java,interface,casting,polymorphism,Java,Interface,Casting,Polymorphism,我有一个现有的方法,如下所示: public void parseMessage(String message){ ... ... ... } 方法是通过如下所示调用它来调用的 String message; parseMessage(message); 我需要修改它以处理新类型的消息。从parseMessage方法调用的新消息类型的解析器希望在解析消息之前先获得一些属性。我想做的是将消息作为如下对象传递 public class MessageObjec

我有一个现有的方法,如下所示:

  public void parseMessage(String message){
    ...
    ...
    ...
  }
方法是通过如下所示调用它来调用的

 String message;
 parseMessage(message);
我需要修改它以处理新类型的消息。从parseMessage方法调用的新消息类型的解析器希望在解析消息之前先获得一些属性。我想做的是将消息作为如下对象传递

public class MessageObject{
  private String message;
  private String namespace;
  private String xmlVersion;
}
然后,我可以将现有方法调用为

 Object messageObject;
 parseMessage(messageObject);
然后我可以通过将它转换为(MessageObject)MessageObject在另一端使用它

这是正确的方法还是有更好的方法。这样做有危险吗

另外,我必须使用上面的转换方法,因为im使用JDK1.4

谢谢

更新 我无法修改parseMessage方法。它内部有一个调用,为每个相关的解析器调用parse()方法

 public void parseMessage(String message){
    ...
    ...
    parser.parse(message)
  }
    package com;

    import java.util.HashMap;

    public class ParserManager{

        public ParserManager() {
            prepare();
        }

        HashMap parsers = new HashMap();


        public void prepare(){

            parsers.put("A",new MessageAParser());
            parsers.put("B",new MessageBParser());
            parsers.put("C",new MessageCParser());
        }

        public void parseMessage(String msgType, String message){
            ((Parser)parsers.get(msgType)).parse(message);
        }
    }


    package com;
上面显示的解析器引用是一个实现接口“parser”的对象。我介绍的新解析器遵循这种结构,并且它还实现了“parser”接口。唯一的修改(即对MessageObject的转换)是在新的解析器中

我无法更改现有的parseMethod,因为这需要更改实现“Parser”接口的所有现有解析器。我希望避免根据消息类型调用特定的解析器

如果我使用我建议的方法,现有解析器仍将接收字符串消息,而新解析器将接收字符串,但它需要首先将其转换回MessageObject

编辑 我不得不根据谢尔盖的评论来测试这一点

接口

    package com;
    public interface Parser{
        public void parse(String message);
    }


    package com;
MessageA解析器

    public class MessageAParser implements Parser{
        public void parse(String message){
            System.out.println("Parsing A");
        }
    }
MessageB解析器

    package com;

    public class MessageAParser implements Parser{
        public void parse(String message){
            System.out.println("Parsing A");
        }
    }
MessageC解析器(这需要一个对象)

调用相关解析器的解析器管理器

 public void parseMessage(String message){
    ...
    ...
    parser.parse(message)
  }
    package com;

    import java.util.HashMap;

    public class ParserManager{

        public ParserManager() {
            prepare();
        }

        HashMap parsers = new HashMap();


        public void prepare(){

            parsers.put("A",new MessageAParser());
            parsers.put("B",new MessageBParser());
            parsers.put("C",new MessageCParser());
        }

        public void parseMessage(String msgType, String message){
            ((Parser)parsers.get(msgType)).parse(message);
        }
    }


    package com;
控制器

    public class ControlClass{

        public static void main(String[] args){

            ParserManager pManager = new ParserManager();

            //Parse A
            pManager.parseMessage("A","ATEXT TO PARSE");

            //Parse B
            pManager.parseMessage("B","BTEXT TO PARSE");

            //Parse C
            Object mobject = new MessageObject();
            pManager.parseMessage("C",(String)mobject);
        }
    }
当我运行上面的控制器类时,它输出前两条消息的文本,但第三条消息失败

Parsing A
Parsing B
java.lang.ClassCastException
    at com.ControlClass.main(ControlClass.java:17)
Exception in thread "main" 

我认为这里有一些更干净的解决方案。首先,您可以扩展实现parseMessage的类并添加其他方法

public void parseMessage(MessageObject messageObject) {
  // Additional stuff here
  ...

  // Call through to original
  parseMessage(messageObject.message);
}

或者,您可以装饰包含parseMessage的类。但是,我假设您可以修改包含parseMessage的类,因为您说无论如何都要在其中强制转换它。

我认为这里有一些更干净的解决方案。首先,您可以扩展实现parseMessage的类并添加其他方法

public void parseMessage(MessageObject messageObject) {
  // Additional stuff here
  ...

  // Call through to original
  parseMessage(messageObject.message);
}

或者,您可以装饰包含parseMessage的类。然而,我假设您可以修改包含parseMessage的类,因为您说无论如何都要在其中强制转换它。

您可以重载parseMessage,因此它有两种风格:一种是采用字符串参数,另一种是采用MessageObject参数。

您可以重载parseMessage,因此它有两种风格:一种是采用字符串参数字符串参数和接受MessageObject参数的参数。

如果要解析的对象类型越来越多,而不是重载解析方法,则应引入一个接口:

public interface Parseable {
    public String getMessage();
}
MessageObject将实现可解析,您可以为字符串对象使用匿名适配器类:

final String m = "theMessageToParse";
parseMessage(new Parseable() {
    public String getMessage() {
        return m;
    }
});

如果要解析的对象类型越来越多,则不应重载解析方法,而应引入一个接口:

public interface Parseable {
    public String getMessage();
}
MessageObject将实现可解析,您可以为字符串对象使用匿名适配器类:

final String m = "theMessageToParse";
parseMessage(new Parseable() {
    public String getMessage() {
        return m;
    }
});

MessageObject类不是String子类,因此不能传递它而不是String。您不能将字符串子类化,因为它被声明为final。因此,无法将MessageObject(无论是什么)传递给现有的parseMessage()函数

我无法更改现有的语法分析方法 因为这将需要改变所有的 实现的现有解析器 “解析器”接口。我想 避免调用特定的解析器 取决于消息类型

Parser.parse()的签名到底是什么?如果它是
parse(String message)
,那么除了字符串之外,您不可能向它传递任何东西

但是,如果这是您不想修改现有parseMessage()的唯一原因,那么有一个解决方法:

public void parseMessage(Object message) { // changed to Object
  ...
  ...
  if (message instanceof String)
    parser.parse((String) message);
  else {
    if (message instanceof MessageObject) {
      if (!(parser instanceof MessageObjectParser)) {
        throw new IllegalArgumentException(
          "A MessageObject is passed, but not supported by the parser");
      }
      ((MessageObjectParser) parser).parse((MessageObject) message);
    } else {
      throw new IllegalArgumentException(
        "Messages of type " + parser.getClass() + " aren't supported");
    }
  }
}

这有点难看,但可能有用。现在,您只有新的解析器实现了新的MessageObjectParser接口,它应该扩展旧的解析器。

MessageObject类不是字符串子类,因此您不能传递它而不是字符串。您不能将字符串子类化,因为它被声明为final。因此,无法将MessageObject(无论是什么)传递给现有的parseMessage()函数

我无法更改现有的语法分析方法 因为这将需要改变所有的 实现的现有解析器 “解析器”接口。我想 避免调用特定的解析器 取决于消息类型

Parser.parse()的签名到底是什么?如果它是
parse(String message)
,那么除了字符串之外,您不可能向它传递任何东西

但是,如果这是您不想修改现有parseMessage()的唯一原因,那么有一个解决方法:

public void parseMessage(Object message) { // changed to Object
  ...
  ...
  if (message instanceof String)
    parser.parse((String) message);
  else {
    if (message instanceof MessageObject) {
      if (!(parser instanceof MessageObjectParser)) {
        throw new IllegalArgumentException(
          "A MessageObject is passed, but not supported by the parser");
      }
      ((MessageObjectParser) parser).parse((MessageObject) message);
    } else {
      throw new IllegalArgumentException(
        "Messages of type " + parser.getClass() + " aren't supported");
    }
  }
}

这有点难看,但可能有用。现在,您只有新的解析器实现了新的MessageObjectParser接口,它应该扩展旧的解析器。

有几个解析器。实现“parser”接口的每个解析器都有一个方法parse(字符串消息)。我添加的新解析器也实现了“parser”接口,它使用签名解析(对象消息)。你确定这行不通吗?我认为既然String是Object的一个子类,它应该可以工作。@ziggy:您可以使用该签名实现解析器,但您还必须实现
parse(String message)
,否则编译器不会接受它作为有效接口