如何在循环中将不同的子类转换为超类?
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()
。
我正在 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()
。