简体   繁体   English

Java-如何调用带字符串的类?

[英]Java-How do I call a class with a string?

I am a beginner programmer and this is my first question on this forum. 我是一个初学者程序员,这是我在这个论坛上的第一个问题。

I am writing a simple text adventure game using BlueJ as a compiler, and I am on a Mac. 我正在使用BlueJ作为编译器编写一个简单的文本冒险游戏,并且在Mac上。 The problem I ran into is that I would like to make my code more self automated, but I cannot call a class with a string. 我遇到的问题是我想使我的代码更加自动化,但是我不能用字符串调用类。 The reason I want call the class and not have it all in an if function is so that I may incorporate more methods. 我想要调用该类而不在if函数中全部包含它的原因是为了使我可以合并更多方法。

Here is how it will run currently: 当前运行方式如下:

public class textadventure {
public method(String room){
if(room==street){street.enterRoom();}
}
}
public class street{
public enterRoom(){
//do stuff and call other methods
}
}

The if statement tests for every class/room I create. if语句对我创建的每个班级/教室进行测试。 What I would like the code to do is automatically make the string room into a class name that can be called. 我希望代码执行的操作是自动将字符串空间设置为可以调用的类名称。 So it may act like so: 因此它可能像这样:

Public method(string room){
Class Room = room;
Room.enterRoom();
}

I have already looked into using Class.forName, but all the examples were too general for me to understand how to use the function. 我已经研究过使用Class.forName,但是所有示例对于我来说太笼统,以至于无法理解如何使用该函数。 Any help would be greatly appreciated, and if there is any other necessary information (such as more example code) I am happy to provide it. 任何帮助将不胜感激,如果有其他必要的信息(例如更多示例代码),我很乐意提供。

-Sebastien -塞巴斯蒂安

Here is the full code: 这是完整的代码:

import java.awt.*;
import javax.swing.*;

public class Player extends JApplet{
public String textOnScreen;

public void start(){
room("street1");
}

public void room(String room){
    if(room=="street1"){
    textOnScreen=street1.enterRoom();
    repaint();
    }
    if(room=="street2"){
    textOnScreen=street2.enterRoom();
    repaint();
    }
}
public void paint(Graphics g){
    g.drawString(textOnScreen,5,15);
}
}

public abstract class street1
{
private static String textToScreen;
public static String enterRoom(){
    textToScreen = "You are on a street running from North to South.";
    return textToScreen;
}
}

public abstract class street2
{
private static String textToScreen;
public static String enterRoom(){
    textToScreen = "You are on another street.";
    return textToScreen;
}
}

Seeing as you are rather new to programming, I would recommend starting with some programs that are simpler than a full-fledged adventure game. 鉴于您是编程的新手,我建议您从一些比成熟的冒险游戏更简单的程序开始。 You still haven't fully grasped some of the fundamentals of the Java syntax. 您仍然没有完全掌握Java语法的一些基础知识。 Take, for example, the HelloWorld program: 以HelloWorld程序为例:

public class HelloWorld {
  public static void main(String[] args) {
    String output = "Hello World!"
    System.out.println(output);
  }   
}

Notice that public is lowercased. 注意public是小写的。 Public with a capital P is not the same as public . 具有大写P Publicpublic

Also notice that the String class has a capital S .* Again, capitalization matters, so string is not the same as String . 还要注意, String类的大小写为S *,大小写也很重要,因此stringString

In addition, note that I didn't have to use String string = new String("string") . 另外,请注意,我不必使用String string = new String("string") You can use String string = "string" . 您可以使用String string = "string" This syntax runs faster and is easier to read. 该语法运行速度更快,更易于阅读。

When testing for string equality, you need to use String.equals instead of == . 测试字符串相等性时,您需要使用String.equals而不是== This is because a == b checks for object equality (ie a and b occupy the same spot in memory) and stringOne.equals(stringTwo) checks to see if stringOne has the same characters in the same order as stringTwo regardless of where they are in memory. 这是因为a == b为对象相等检查(即ab占用在存储器中的相同的点)和stringOne.equals(stringTwo)检查是否stringOne具有相同的字符以相同的次序作为stringTwo无论他们在哪里在记忆中。

Now, as for your question, I would recommend using either an Enum or a Map to keep track of which object to use. 现在,关于您的问题,我建议您使用EnumMap来跟踪要使用的对象。

For example: 例如:

public class Tester {

  public enum Location {

    ROOM_A("Room A", "You are going into Room A"),
    ROOM_B("Room B", "You are going into Room B"),
    OUTSIDE("Outside", "You are going outside");
    private final String name;
    private final String actionText;

    private Location(String name, String actionText) {
      this.name = name;
      this.actionText = actionText;
    }

    public String getActionText() {
      return this.actionText;
    }   

    public String getName() {
      return this.name;
    }   

    public static Location findByName(String name) {
      name = name.toUpperCase().replaceAll("\\s+", "_");
      try {
        return Enum.valueOf(Location.class, name);
      } catch (IllegalArgumentException e) {
        return null;
      }   
    }   
  }


  private Location currentLocation;

  public void changeLocation(String locationName) {
    Location location = Location.findByName(locationName);
    if (location == null) {
      System.out.println("Unknown room: " + locationName);
    } else if (currentLocation != null && currentLocation.equals(location)) {
      System.out.println("Already in room " + location.getName());
    } else {
      System.out.println(location.getActionText());
      currentLocation = location;
    }
  }

  public static void main(String[] args) {
    Tester tester = new Tester();
    tester.changeLocation("room a");
    tester.changeLocation("room b");
    tester.changeLocation("room c");
    tester.changeLocation("room b");
    tester.changeLocation("outside");
  }
}

*This is the standard way of formating Java code. *这是格式化Java代码的标准方式。 Class names are PascalCased while variable names are camelCased . 类名是PascalCased ,变量名是camelCased

String className=getClassName();//Get class name from user here
String fnName=getMethodName();//Get function name from user here

Class params[] = {};
Object paramsObj[] = {};

Class thisClass = Class.forName(className);// get the Class

Object inst = thisClass.newInstance();// get an instance
// get the method
Method fn = thisClass.getDeclaredMethod(fnName, params);
// call the method
fn.invoke(inst, paramsObj);

The comments below your question are true - your code is very rough. 问题下方的注释是正确的-您的代码很粗糙。

Anyway, if you have a method like 无论如何,如果您有类似的方法

public void doSomething(String str) {
  if (str.equals("whatever")) {
    // do something
  }
}

Then call it like 然后像这样称呼它

doSomething("whatever");

In Java, many classes have attributes, and you can and will often have multiple instances from the same class. 在Java中,许多类都具有属性,并且您可以而且经常会拥有同一类的多个实例。

How would you identify which is which by name? 您将如何识别哪个名字呢?

For example 例如

class Room {
    List<Monster> monsters = new ArrayList <Monster> ();
    public Room (int monstercount) {
         for (int i = 0; i < monstercount; ++i)
            monsters.add (new Monster ());
    }
    // ...
}

Monsters can have attributes, and if one of them is dead, you can identify it more easily if you don't handle everything in Strings. 怪物可以具有属性,如果其中之一已消失,则如果不处理字符串中的所有内容,则可以更轻松地识别它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM