java - 在 Java 中是否可以在不使用关键字“implements”的情况下实现接口及其方法?
问题描述
我有功课要做(实际上是我的女朋友:-D),我能做什么和不能做什么有一些限制。在我的 NetBeans 项目文件夹中有两个名为“interfaces”和“homework”的文件夹。文件夹“interfaces”包含不允许编辑的接口和类,因为对我们说 xD。我只被允许编辑“作业”文件夹中的源文本。
通常,我知道用关键字“implements”在 Java 中实现接口。但是我不知道如何在“homework”文件夹中使用它,因为“interfaces”文件夹已经包含了实现接口的方法和逻辑的类,但是我不允许编辑它们。
这是任务:
“我们在“interfaces”包中为您提供了各种接口,您必须自己实现。您只能在“homework”包中创建自己的实现。您不得修改“interfaces”包的类和接口!
“TextAdventure”界面,您必须实现的方法,允许您创建文本冒险游戏。在“作业”包中,您将找到一个使用 TextAdventure 接口初始化各种游戏的 Main 类。在成功实现所期望的接口后,您可以玩该游戏。游戏场景旨在帮助您广泛测试您的代码。Interface Player 的所有方法都可用于与游戏交互。还要看一下 GameStarter 类。在此,实现了与玩家的交互。
TextAdventure 界面提供了各种创建新游戏的方法。对于每种方法,请考虑它可能失败的情况。在这种情况下,抛出 TextAdventureException。这也在“interfaces”包中提供给您。一旦建立了所需的初始状态,就可以使用“startGame()”开始游戏。
接口:
package interfaces;
import homework.Factory;
/**
* Class with text adventure scenarios to play.
*/
public class Adventures {
/**
* Initialize the fireman-game.
*
* @return the fireman-game
* @throws TextAdventureException
*/
public static interfaces.TextAdventure getFiremanGame() throws TextAdventureException {
interfaces.TextAdventure textAdventure = Factory.getGame("Sample1", 2, 2);
textAdventure.addSceneryType("BurningTree", "A blazing fire on an oak tree.");
textAdventure.addSceneryType("HalfBurningTree", "A little fire on an oak tree.");
textAdventure.addItemType("Bucket", "An empty bucket.");
textAdventure.addItemType("Water", "A bucket full of water.");
textAdventure.addItemType("Head", "Kopf");
textAdventure.addItemType("Headweh", "Jetzt brummt de kopf");
textAdventure.addSceneryType("Lake", "A beautiful lake.");
textAdventure.addSceneryType("CharredOak", "A poor, charred oak tree.");
textAdventure.addTransformation("Bucket", "Lake", "Water", "Lake",
"Now you got a bucket full of water.");
textAdventure.addTransformation("Water", "BurningTree", "HalfBurningTree", "Bucket",
"The water quenches the fire. But not completely.");
textAdventure.addTransformation("Water", "HalfBurningTree", "CharredOak", "Bucket",
"The water quenches the fire.");
textAdventure.addComposition("Bucket", "Head", "Headweh", "Kopfwehh");
textAdventure.placeItem("Lake", 0, 0);
textAdventure.placeItem("Bucket", 1, 1);
textAdventure.placeItem("Head", 1, 1);
textAdventure.placeItem("BurningTree", 0, 0);
return textAdventure;
}
/**
* Initialize the lumberjack-game.
*
* @return The lumberjack-game
* @throws TextAdventureException
*/
public static interfaces.TextAdventure getLumberjackGame() throws TextAdventureException {
interfaces.TextAdventure textAdventure = Factory.getGame("Sample2", 1, 1);
textAdventure.addSceneryType("Tree", "A lush green tree.");
textAdventure.addItemType("Wood", "Some pieces of wood");
textAdventure.addSceneryType("Roots", "The sad roots of a former tree.");
textAdventure.addDecomposition("Tree", "Wood", "Roots", "You fell the tree and get some wood.");
textAdventure.placeItem("Tree", 0, 0);
return textAdventure;
}
/**
* Initialize the pokemon-game.
*
* @return the pokemon-game
* @throws TextAdventureException
*/
public static interfaces.TextAdventure getPokemonGame() throws TextAdventureException {
TextAdventure textAdventure = Factory.getGame("Pokemon", 50, 50);
textAdventure.addItemType("Coin", "One coin");
textAdventure.addItemType("Money", "Many coins");
textAdventure.addItemType("Bisasam", "Look, a wild Bisasam.");
textAdventure.addItemType("Glumanda", "Look, a wild Glumanda.");
textAdventure.addItemType("Schiggy", "Look, a wild Schiggy.");
textAdventure.addItemType("Bisaknosp", "Bisaknosp eats plants.");
textAdventure.addItemType("Glutexo", "Glutexo burns.");
textAdventure.addItemType("Schillok", "Schillok swimming around.");
textAdventure.addItemType("Bisaflor", "Bisaflor eats plants.");
textAdventure.addItemType("Glurak", "Glurak burns.");
textAdventure.addItemType("Turtok", "Turtok swimming around.");
textAdventure.addItemType("Taubsi", "Taubsi flying around.");
textAdventure.addItemType("Tauboga", "Tauboga flying around.");
textAdventure.addItemType("Tauboss", "Tauboss flying around.");
textAdventure.addItemType("Mewtu", "Mewtu sees dead people.");
textAdventure.addItemType("Developmentstone",
"The Developmentstone brings your Pokemon to the next Level.");
textAdventure.addItemType("Attackstone",
"The Attackstone is in combination with your Pokemon to attack other Pokemons.");
textAdventure.addItemType("Pokeball",
"Pokeball is there to catch other Pokemons.");
textAdventure.addSceneryType("Wildtaubsi", "Look, a wild Taubsi.");
textAdventure.addSceneryType("Deadtaubsi", "Look, a dead Taubsi.");
textAdventure.addSceneryType("Silvertreasure", "Look, a Treasure.");
textAdventure.addSceneryType("Goldtreasure", "Look, a Treasure.");
textAdventure.placeItem("Coin", 0, 0);
textAdventure.placeItem("Bisasam", 0, 0);
textAdventure.placeItem("Glumanda", 0, 0);
textAdventure.placeItem("Schiggy", 0, 0);
textAdventure.placeItem("Developmentstone", 2, 4);
textAdventure.placeItem("Developmentstone", 25, 31);
textAdventure.placeItem("Developmentstone", 49, 11);
textAdventure.placeItem("Developmentstone", 22, 22);
textAdventure.placeItem("Developmentstone", 11, 44);
textAdventure.placeItem("Developmentstone", 23, 43);
textAdventure.placeItem("Developmentstone", 39, 1);
textAdventure.placeItem("Developmentstone", 22, 21);
textAdventure.placeItem("Developmentstone", 45, 30);
textAdventure.placeItem("Developmentstone", 10, 12);
textAdventure.placeItem("Developmentstone", 23, 1);
textAdventure.placeItem("Developmentstone", 49, 49);
textAdventure.placeItem("Developmentstone", 17, 15);
textAdventure.placeItem("Attackstone", 1, 1);
textAdventure.placeItem("Attackstone", 10, 10);
textAdventure.placeItem("Attackstone", 20, 20);
textAdventure.placeItem("Attackstone", 30, 30);
textAdventure.placeItem("Attackstone", 4, 5);
textAdventure.placeItem("Attackstone", 10, 2);
textAdventure.placeItem("Attackstone", 23, 44);
textAdventure.placeItem("Attackstone", 30, 35);
textAdventure.placeItem("Pokeball", 1, 1);
textAdventure.placeItem("Pokeball", 3, 22);
textAdventure.placeItem("Pokeball", 17, 21);
textAdventure.placeItem("Pokeball", 33, 13);
textAdventure.placeItem("Pokeball", 45, 22);
textAdventure.placeItem("Pokeball", 21, 13);
textAdventure.placeItem("Pokeball", 19, 41);
textAdventure.placeItem("Pokeball", 12, 32);
textAdventure.placeItem("Wildtaubsi", 2, 2);
textAdventure.placeItem("Wildtaubsi", 23, 24);
textAdventure.placeItem("Wildtaubsi", 11, 7);
textAdventure.placeItem("Wildtaubsi", 3, 9);
textAdventure.placeItem("Wildtaubsi", 32, 45);
textAdventure.placeItem("Wildtaubsi", 31, 29);
textAdventure.placeItem("Wildtaubsi", 17, 31);
textAdventure.placeItem("Wildtaubsi", 45, 45);
textAdventure.placeItem("Wildtaubsi", 18, 32);
textAdventure.placeItem("Wildtaubsi", 26, 42);
textAdventure.placeItem("Wildtaubsi", 42, 26);
textAdventure.placeItem("Wildtaubsi", 17, 49);
textAdventure.placeItem("Wildtaubsi", 11, 22);
textAdventure.placeItem("Wildtaubsi", 36, 39);
textAdventure.placeItem("Wildtaubsi", 31, 24);
textAdventure.placeItem("Silvertreasure", 2, 3);
textAdventure.placeItem("Silvertreasure", 32, 33);
textAdventure.placeItem("Silvertreasure", 14, 13);
textAdventure.placeItem("Silvertreasure", 47, 11);
textAdventure.placeItem("Silvertreasure", 12, 34);
textAdventure.placeItem("Silvertreasure", 21, 33);
textAdventure.placeItem("Silvertreasure", 43, 21);
textAdventure.placeItem("Silvertreasure", 49, 3);
textAdventure.placeItem("Silvertreasure", 12, 49);
textAdventure.placeItem("Silvertreasure", 41, 34);
textAdventure.placeItem("Silvertreasure", 12, 33);
textAdventure.placeItem("Silvertreasure", 22, 34);
textAdventure.placeItem("Silvertreasure", 1, 40);
textAdventure.placeItem("Silvertreasure", 19, 28);
textAdventure.placeItem("Silvertreasure", 45, 32);
textAdventure.placeItem("Silvertreasure", 21, 23);
textAdventure.placeItem("Goldtreasure", 33, 34);
textAdventure.addComposition("Coin", "Coin", "Money", "You made money");
textAdventure.addComposition("Bisasam", "Developmentstone", "Bisaknosp",
"Look your Bisasam has developed to Bisaknosp.");
textAdventure.addComposition("Glumanda", "Developmentstone", "Glutexo",
"Look your Glumanda has developed to Glutexo.");
textAdventure.addComposition("Schiggy", "Developmentstone", "Schillok",
"Look your Schiggy has developed to Schillok.");
textAdventure.addComposition("Taubsi", "Developmentstone", "Tauboga",
"Look your Taubsi has developed to Tauboga");
textAdventure.addComposition("Bisaknosp", "Developmentstone", "Bisaflor",
"Look your Bisaknosp has developed to Bisaflor");
textAdventure.addComposition("Glutexo", "Developmentstone", "Glurak",
"Look your Glutexo has developed to Glurak");
textAdventure.addComposition("Schillok", "Developmentstone", "Turtok",
"Look your Schillok has developed to Turtok");
textAdventure.addComposition("Tauboga", "Developmentstone", "Tauboss",
"Look your Tauboga has developed to Tauboss");
textAdventure.addComposition("Wildtaubsi", "Attackstone", "Deadtaubsi",
"Your Pokemon attacks the wild Taubsi. Taubsi is dead.");
textAdventure.addComposition("Wildtaubsi", "Pokeball", "Taubsi",
"You have catch Taubsi. Congratulations, Taubsi is your new Pokemon.");
textAdventure.addDecomposition("Silvertreasure", "Developmentstone",
"Attackstone",
"You open the treasure and you find an Attack- and Developmentstone.");
textAdventure.addDecomposition("Goldtreasure", "Pokeball", "Mewtu",
"See, you find the unique Mewtu.");
textAdventure.addTransformation("Taubsi", "Attackstone", "Taubsi",
"Developmentstone",
"Look, your Taubsi transform the Attackstone to a Developmentstone.");
textAdventure.addTransformation("Tauboga", "Attackstone", "Tauboga",
"Developmentstone",
"Look, your Tauboga transform the Attackstone to a Developmentstone.");
textAdventure.addTransformation("Tauboss", "Attackstone", "Tauboss",
"Developmentstone",
"Look, your Tauboss transform the Attackstone to a Developmentstone.");
textAdventure.addTransformation("Mewtu", "Developmentstone", "Mewtu",
"Attackstone",
"Look, your Mewtu transform the Developmentstone to a Attackstone.");
textAdventure.addTransformation("Bisasam", "Attackstone", "Bisasam",
"Pokeball",
"Look, your Bisasam transform the Attackstone to a Pokeball.");
textAdventure.addTransformation("Bisaknosp", "Attackstone", "Bisaknosp",
"Pokeball",
"Look, your Bisaknosp transform the Attackstone to a Pokeball.");
textAdventure.addTransformation("Bisaflor", "Attackstone", "Bisaflor",
"Pokeball",
"Look, your Bisaflor transform the Attackstone to a Pokeball.");
textAdventure.addTransformation("Glumanda", "Pokeball", "Glumanda",
"Developmentstone",
"Look, your Glumanda transform the Pokeball to a Developmentstone.");
textAdventure.addTransformation("Glutexo", "Pokeball", "Glutexo",
"Developmentstone",
"Look, your Glutexo transform the Pokeball to a Developmentstone.");
textAdventure.addTransformation("Glurak", "Pokeball", "Glurak",
"Developmentstone",
"Look, your Glurak transform the Pokeball to a Developmentstone.");
textAdventure.addTransformation("Schiggy", "Pokeball", "Schiggy",
"Attackstone",
"Look, your Schiggy transform the Pokeball to a Attackstone.");
textAdventure.addTransformation("Schillok", "Pokeball", "Schillok",
"Attackstone",
"Look, your Schillok transform the Pokeball to a Attackstone.");
textAdventure.addTransformation("Turtok", "Pokeball", "Turtok",
"Attackstone",
"Look, your Turtok transform the Pokeball to a Attackstone.");
return textAdventure;
}
}
package interfaces;
import homework.Factory;
/**
* Class integrates the implementation of the student package and allows to play the text adventure scenarios.
*/
public class GameStarter {
private static final String PROMPT = "play>";
private static Player player;
private Terminal terminal;
private TextAdventure[] games;
/**
* Constructor to create a GameStarter instance.
* @param games array with text adventures games to play
*/
public GameStarter(TextAdventure[] games) {
terminal = Factory.getTerminal();
this.games = games;
}
/**
* Starts one of the given games.
*/
public void startGame() {
String[] input;
String prompt = "Play (";
for (TextAdventure game : this.games) {
prompt += game.getName();
prompt += "|";
}
prompt = prompt.substring(0, prompt.length() - 1) + ")";
do {
terminal.promptInput(prompt);
input = terminal.readInput();
} while (input[0].equals("") || input[0].equals(" "));
String gameName = input[0];
for (TextAdventure game : this.games) {
if (game.getName().equals(gameName)) {
startGame(game, 0, 0);
return;
}
}
System.out.println("Unknown game scenario");
System.exit(1);
}
/**
* Starts a given game and runs a simple input-loop that accepts game-commands.
* @param textAdventure to play
* @param x coordinate of the player
* @param y coordinate of the player
*/
public void startGame(TextAdventure textAdventure, int x, int y) {
try {
player = textAdventure.startGame(x, y);
} catch (TextAdventureException e) {
System.out.println(e.getMessage());
System.exit(1);
}
boolean run = true;
while (run) {
try {
terminal.promptInput(PROMPT);
String[] input = terminal.readInput();
run = processInput(input);
} catch (TextAdventureException e) {
System.out.println(e.getMessage());
}
}
}
/**
* Process the given command-line, translate it into player-actions if possible.
* @param input the splitted user input
* @return false if the user wants to quit, true otherwise
* @throws TextAdventureException If an invalid command is entered
*/
private static boolean processInput(String[] input) throws TextAdventureException {
switch (input[0]) {
case "go": {
if (input.length < 2) {
System.out.println("Sorry, please specify a direction.");
} else {
System.out.println(player.go(input[1]));
}
return true;
}
case "look": {
String[] list = player.look();
for (String line : list) {
System.out.println(line);
}
return true;
}
case "inventory": {
String[] list = player.inventory();
for (String line : list) {
System.out.println(line);
}
return true;
}
case "take": {
if (input.length < 2) {
System.out.println("Sorry, please specify an object.");
} else {
System.out.println(player.take(input[1]));
}
return true;
}
case "drop": {
if (input.length < 2) {
System.out.println("Sorry, please specify an object.");
} else {
System.out.println(player.drop(input[1]));
}
return true;
}
case "convert": {
if (input.length < 3) {
System.out.println("Sorry, please specify the objects to compose.");
} else {
System.out.println(player.convert(input[1], input[2]));
}
return true;
}
case "decompose": {
if (input.length < 2) {
System.out.println("Sorry, please specify an object.");
} else {
System.out.println(player.decompose(input[1]));
}
return true;
}
case "help": {
System.out.println("Valid Commands are: go, look, inventory, take, drop, compose, decompose");
return true;
}
case "exit": {
System.out.println("Bye!");
return false;
}
default: {
throw new TextAdventureException("Unknown Command: " + input[0]);
}
}
}
}
package interfaces;
/**
* Models the interface of a text adventure player.
*/
public interface Player {
/**
* Move the player's token into direction.
* @param direction One of eight valid directions "N", "NE", "E", "SE", "S", "SW", "W", "NW"
* @return A ui-message for the user
*/
String go(String direction);
/**
* Returns an array of objects on the current field.
* @return An array of object-type and descriptions for the ui
*/
String[] look();
/**
* Returns an array of objects in the inventory.
* @return An array of object-type and descriptions for the ui
*/
String[] inventory();
/**
* Removes an object of the given type from the current field and adds it to the inventory.
* @param item An object-type
* @return A ui-message for the user
*/
String take(String item);
/**
* Removes an object of the given type from the inventory and adds it to the current field.
* @param item An object-type
* @return A ui-message for the user
*/
String drop(String item);
/**
* Applies a transformation- or composition-rule to item1 and item2.
* If possible, removes item1 and item2 from the current field or inventory
* and adds the mutation-result to the current field or inventory,
* depending on the object's base-type (scenery or item).
* @param item1 An Object-Type
* @param item2 An Object-Type
* @return A ui-message for the user
*/
String convert(String item1, String item2);
/**
* Applies a decomposition-rule to item.
* If possible, removes item from the current field or inventory
* and adds the mutation-result to the current field or inventory,
* depending on the object's base-type (scenery or item).
* @param item An Object-Type
* @return A ui-message for the user
*/
String decompose(String item);
}
package interfaces;
/**
* Models the interface of terminal to interact with a player.
*/
public interface Terminal {
/**
* Prompts the user to enter a string as input. The string is printed to the standard output (terminal).
*
* @param input the message to display the player
*/
public void promptInput(String input);
/**
* Reads the user input and returns splitted at spaces as string array.
* @return splitted user input string
*/
public String[] readInput();
}
package interfaces;
/**
* Models the interface of a text adventure game-instance.
*/
public interface TextAdventure {
/**
* Declares a new portable object-type with given id and description.
* @param id The id object-type, used in the ui to search for objects
* @param description The description of the object-type
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void addItemType(String id, String description) throws TextAdventureException;
/**
* Declares a new non-portable object-type with given id and description.
* @param id The id object-type, used in the ui to search for objects
* @param description The description of the object-type
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void addSceneryType(String id, String description) throws TextAdventureException;
/**
* Adds a new object of the given type to the field at the specified position.
* @param type The id of an object-type
* @param x A field coordinate on the board
* @param y A field coordinate on the board
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void placeItem(String type, int x, int y) throws TextAdventureException;
/**
* Adds a new composition-rule to the set of mutation-rules.
* @param in1 Object-type id of the input-object
* @param in2 Object-type id of the input-object
* @param out Object-type id of the output-object
* @param description Mutation-description for the ui
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void addComposition(String in1, String in2, String out, String description) throws TextAdventureException;
/**
* Adds a new decomposition-rule to the set of mutation-rules.
* @param in Object-type id of the input-object
* @param out1 Object-type id of the output-object
* @param out2 Object-type id of the output-object
* @param description Mutation-description for the ui
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void addDecomposition(String in, String out1, String out2, String description) throws TextAdventureException;
/**
* Adds a new transformation-rule to the set of mutation-rules.
* @param in1 in1 Object-type id of the input-object
* @param in2 in1 Object-type id of the input-object
* @param out1 Object-type id of the output-object
* @param out2 Object-type id of the output-object
* @param description Mutation-description for the ui
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
void addTransformation(String in1, String in2, String out1, String out2, String description)
throws TextAdventureException;
/**
* Initializes a new game instance and returns a player-instance for game-control.
* The player's initial position is at the given coordinates
* @param x A field coordinate on the board
* @param y A field coordinate on the board
* @return A player-instance for game-control
* @throws TextAdventureException Think about the cases in which an exception is useful and implement it.
*/
Player startGame(int x, int y) throws TextAdventureException;
/**
* Returns the name of the game instance.
* @return the name of the game instance
*/
String getName();
}
package interfaces;
/**
* General Exception-type of the text adventure framework.
*/
public class TextAdventureException extends Exception {
/**
* Exception Prefix.
*/
public static final String ERROR = "Error! ";
/**
* Creates a new TextAdventureException with the given message.
* @param message The error-message
*/
public TextAdventureException(String message) {
super(ERROR + message);
}
}
package homework;
/**
* Factory class with functions to generate a game and terminal.
*/
public final class Factory {
private Factory() { }
public static interfaces.TextAdventure getGame(String name, int boardWidth, int boardHeight)
throws interfaces.TextAdventureException {
//placeholder
return null;
}
/**
* Creates a new terminal-instance to read user input and prompt messages.
* @return a terminal instance
*/
public static interfaces.Terminal getTerminal() {
//placeholder
return null;
}
}
打包作业;公共类主要{
public static void main(String[] args) {
try {
// Add additional games to the Array
TextAdventure[] games = {
Adventures.getFiremanGame(), Adventures.getLumberjackGame(), Adventures.getPokemonGame()
};
GameStarter starter = new GameStarter(games);
starter.startGame();
} catch (TextAdventureException e) {
e.printStackTrace();
}
}
}
解决方案
您可以实现接口 X 声明的所有方法,而无需编写“实现 X”。但这真的很荒谬。您希望 Java 编译器了解您的新类实现了 X。为此,您需要在类定义的签名上使用该关键字。
可以考虑扩展一个已经实现接口的类,那么您不必重复关键字“实现 X”。但这实际上只是在源代码中不使用该关键字。
在您的情况下,关键部分是要了解到目前为止,该包接口中的所有接口都没有实现。你的出发点:只写下你收到的输入中存在的类和接口的名称列表。然后看看哪个接口有实现,哪个没有!