[英]How do I set a parameterized type of a variable to the type of class the variable is in?
我正在制作一個具有多個“命令功能”的 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;
}
}
每個功能都有幾個命令(MyBotCommand)。 MyBotCommand 有兩種抽象方法用於處理文本命令 (runTextCommand) 和斜線命令 (runSlashCommand)。
因為某些命令會想要引用它們所屬的MyBotFeature
, MyBotCommandFeature
當前是這些抽象方法的參數之一。 但是,要使用任何特定於功能的功能,命令當前必須將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
}
});
}
我希望我能夠使用泛型類型<F extends MyBotCommandFeature>
對MyBotCommand
進行參數化。 然后,它們不是將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);
}
但是,我不確定我是否會聲明命令集的類型(在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
}
});
}
我試過使用通配符'? 而不是“this”,但是在將 JDA 事件與 MyBotCommand 匹配后,我被困在傳遞給抽象方法的內容上。 例如,我有這個用於斜杠命令,但我無法將 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;
}
}
}
}
有什么辦法可以做這樣的事情嗎? 如果沒有,是否有另一種方法可以避免在我的大多數MyBotCommand
實現MyBotCommandFeature
轉換為單個功能?
這樣的事情怎么樣? MyBotCommand
MyBotCommandFeature
類型參數。 然后子類ExampleFeature
可以擴展MyBotCommandFeature
並將其自身作為類型參數。 當然,有人可以編寫一個類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.