如何在循环中将不同的子类转换为超类?

How to cast a different subclass to a superclass in a loop?

我正在 Java 中编写标记解析器。我已经为基于超类(通用?)的每种令牌创建了 类,我正在调用 BaseToken。每个标记内都有一个 Pattern 对象和一个 String 内容。我正在编写一个函数,它从字符串中的某个起点找到字符串中最近的标记。为了找出哪种模式最有效,我创建了一个 BaseToken 实例数组,在测试时会循环这些实例。

BaseToken 定义为:

public class BaseToken{
    public Pattern pattern = null;
    private BaseToken[] children;
}

BaseToken 的子类示例如下所示:

public class H3 extends BaseToken{
    public Pattern pattern = Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
}

我的问题是,为了访问特定于子类的 Pattern,我需要专门将该子类转换为其在数组中的实例。由于每个循环的标记类型都不同,我不能只用 (subclass)instance.

来转换它

我尝试搜索与我的情况类似的情况,但实际上我不知道要搜索什么。如果这是现有问题的重复,我很抱歉。

这不是利用多态性的最佳方式。您应该将 BaseToken 变成接口或抽象 class,并创建一个特定于操作模式的方法。然后,您应该让子类型实现该方法,以便每个 class 都可以以自己的方式 操纵自己的模式(应该是 class 私有的)而不破坏调用代码(你应该阅读 Liskov 的替换原则)。

一个简单的例子:

abstract class BaseToken {
   abstract Pattern getPattern();
}

class H3 extends BaseToken {
  private Pattern pattern = ...

  Pattern getPattern() {
    return pattern;
  }
}

class Whatever extends BaseToken {
  private Pattern aCompletelyDifferentPattern = ...

  Pattern getPattern() {
    return aCompletelyDifferentPattern;
  }
}

有了这个,您现在可以执行以下操作:

BaseToken token = new H3();
Pattern currentPattern = token.getPattern();

无论你使用什么子class,这总是return相应的模式。

我建议你把BaseToken写成摘要 class:

public abstract class BaseToken {
    public abstract Pattern getPattern();

    /* ...other stuff */
}

然后,您的各种令牌可以扩展它和return它们的特定模式:

public class H3 extends BaseToken {
    public Pattern getPattern() {
        return Pattern.compile("\=\=\=([^\s*].*?)\=\=\=");
    }
}

拥有 BaseToken bt(并且不知道其确切的子类型)您仍然可以调用 bt.getPattern()