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

时间:2018-11-21 19:16:41

标签: java subclass superclass

我正在用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对其进行强制转换。

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

2 个答案:

答案 0 :(得分:2)

这不是利用多态性的最佳方法。您应该将BaseToken转换为接口或抽象类,并创建特定于操作模式的方法。然后,您应该让子类型实现该方法,以便每个类都可以以自己的方式在不破坏调用代码的情况下操作自己的模式(该模式应为该类专用)(您应该阅读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();

无论您使用什么子类,都将始终返回相应的模式。

答案 1 :(得分:1)

我建议您将BaseToken设置为抽象类:

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

    /* ...other stuff */
}

然后,您的各种令牌可以对其进行扩展并返回其特定模式:

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

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