[英]How do I set a parameterized type of a variable to the type of class the variable is in?
I am making a Discord bot with several 'command features'我正在制作一个具有多个“命令功能”的 Discord 机器人
public class MyBotCommandFeature extends MyBotFeature {
@NotNull public final Set<MyBotCommand> commands;
public MyBotCommandFeature(@NotNull MyBotCommand @NotNull ... commands) {
if (commands.length == 0) {
this.commands = new HashSet<>();
} else {
this.commands = stream(commands).collect(Collectors.toSet());
}
}
@Nullable
@CheckForNull
@CheckReturnValue
public Set<MyBotCommand> getExtraCommands(@NotNull Guild guild) {
return null;
}
}
Each feature has several commands (MyBotCommand).每个功能都有几个命令(MyBotCommand)。 MyBotCommand has two abstract methods for handling text commands (runTextCommand) and slash commands (runSlashCommand).
MyBotCommand 有两种抽象方法用于处理文本命令 (runTextCommand) 和斜线命令 (runSlashCommand)。
Because some commands will want to refer to the MyBotFeature
they're a part of, MyBotCommandFeature
is currently one of the parameters of these abstract methods.因为某些命令会想要引用它们所属的
MyBotFeature
, MyBotCommandFeature
当前是这些抽象方法的参数之一。 However, to use any feature-specific features, commands currently have to cast MyBotCommandFeature
to, say, ExampleCommandFeature
.但是,要使用任何特定于功能的功能,命令当前必须将
MyBotCommandFeature
为ExampleCommandFeature
。
public abstract class MyBotCommand {
public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull MyBotCommandFeature feature);
public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull MyBotCommandFeature feature);
}
public final class ExampleFeature extends MyBotCommandFeature {
public ExampleFeature() {
super(new MyBotCommand() {
@Override
public void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull MyBotCommandFeature feature) {
final ExampleFeature self = ((ExampleFeature) feature);
// Use self to respond to the text command
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull MyBotCommandFeature feature) {
final ExampleFeature self = ((ExampleFeature) feature);
// Use self to respond to the slash command
}
});
}
I was hoping I'd be able to make MyBotCommand
be parameterized with the generic type <F extends MyBotCommandFeature>
.我希望我能够使用泛型类型
<F extends MyBotCommandFeature>
对MyBotCommand
进行参数化。 Then instead of the abstract functions taking MyBotCommandFeature
as parameters, they'd take F
.然后,它们不是将
MyBotCommandFeature
作为参数的抽象函数,而是采用F
。
public abstract class MyBotCommand<F extends MyBotCommandFeature> {
public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull F feature);
public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull F feature);
}
However, I'm not sure I would then declare the type of the set of commands (defined in MyBotCommandFeature
, not individually in each feature) to say that the generic type F is the same as the class the set of commands is being stored in. I would want to be able to do something like this.但是,我不确定我是否会声明命令集的类型(在
MyBotCommandFeature
中定义,而不是在每个功能中单独定义)来说明通用类型 F 与存储命令集的类相同.我希望能够做这样的事情。
public class MyBotCommandFeature extends MyBotFeature {
@NotNull public final Set<MyBotCommand<this>> commands;
public MyBotCommandFeature(@NotNull MyBotCommand<this> @NotNull ... commands) {
if (commands.length == 0) {
this.commands = new HashSet<>();
} else {
this.commands = stream(commands).collect(Collectors.toSet());
}
}
@Nullable
@CheckForNull
@CheckReturnValue
public Set<MyBotCommand<this>> getExtraCommands(@NotNull Guild guild) {
return null;
}
}
public final class ExampleFeature extends MyBotCommandFeature {
public ExampleFeature() {
super(new MyBotCommand<ExampleFeature>() {
@Override
public void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull ExampleFeature feature) {
// Use feature to respond to the text command
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull ExampleFeature feature) {
// Use feature to respond to the text command
}
});
}
I have tried using a wildcard '?'我试过使用通配符'? instead of 'this' but then I'm stuck on what to pass to the abstract methods after matching a JDA event to a MyBotCommand.
而不是“this”,但是在将 JDA 事件与 MyBotCommand 匹配后,我被困在传递给抽象方法的内容上。 For example, I have this for slash commands, but I am unable to pass MyBotCommandFeature to MyBotCommand::runSlashCommand even though the MyBotCommand instance is made in the MyBotCommandFeature I am passing.
例如,我有这个用于斜杠命令,但我无法将 MyBotCommandFeature 传递给 MyBotCommand::runSlashCommand,即使 MyBotCommand 实例是在我传递的 MyBotCommandFeature 中创建的。
@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
for (MyBotCommandFeature feature : features) {
for (MyBotCommand<?> command : feature.commands) {
if (command.name.equals(event.getName())) {
command.runSlashCommand(event,feature);
return;
}
}
}
}
Is there some way I can do something like this?有什么办法可以做这样的事情吗? If not, is there an alternative way to avoid having to cast
MyBotCommandFeature
to an individual feature in most of my MyBotCommand
implementations?如果没有,是否有另一种方法可以避免在我的大多数
MyBotCommand
实现MyBotCommandFeature
转换为单个功能?
How about something like this?这样的事情怎么样? There is a type variable on
MyBotCommandFeature
indicating the type argument of the MyBotCommand
that its commands are. MyBotCommand
MyBotCommandFeature
类型参数。 Then the subclass ExampleFeature
can extend MyBotCommandFeature
with itself as the type argument.然后子类
ExampleFeature
可以扩展MyBotCommandFeature
并将其自身作为类型参数。 Of course, someone could write a class FeatureA extends MyBotCommandFeature<FeatureB>
, but everything is still type-safe and should compile without any warnings or casts, at least with what you've shown so far.当然,有人可以编写一个类
FeatureA extends MyBotCommandFeature<FeatureB>
,但一切仍然是类型安全的,并且应该在没有任何警告或强制转换的情况下编译,至少与您目前所展示的一样。
public abstract class MyBotCommand<F> {
public abstract void runTextCommand(@NotNull MessageReceivedEvent event, @NotNull F feature);
public abstract void runSlashCommand(@NotNull SlashCommandInteractionEvent event, @NotNull F feature);
}
public class MyBotCommandFeature<F> extends MyBotFeature {
@NotNull public final Set<MyBotCommand<F>> commands;
public MyBotCommandFeature(@NotNull MyBotCommand<F> @NotNull ... commands) {
if (commands.length == 0) {
this.commands = new HashSet<>();
} else {
this.commands = stream(commands).collect(Collectors.toSet());
}
}
@Nullable
@CheckForNull
@CheckReturnValue
public Set<MyBotCommand<F>> getExtraCommands(@NotNull Guild guild) {
return null;
}
}
public final class ExampleFeature extends MyBotCommandFeature<ExampleFeature> {
public ExampleFeature() {
super(new MyBotCommand<ExampleFeature>() {
// ...
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.