如何检查子对象是否属于特定类(而不是父类)(Java)

3

我需要为学校写一个基于文字的小游戏,其中包括Player类和Computer类。在Game类中,我需要区分这两个类,以便只在玩家不是计算机时打印指令。

public class Player {
    private String name;

    public Player(String name) {
        this.name = name;
    }
}

public class Computer extends Player {
    public Computer(String name) {
        super(name);
    }
}

我尝试了以下方法:

player1 = new Player;

if(player1.getClass() != Computer.class) {
    System.out.println("Your turn, player 1.");
}

这应该会打印“轮到你了,玩家1。”,因为玩家不是计算机,对吗?但事实并非如此,我不知道该怎么做。
我已经尝试了instanceof,但它总是返回true,因为计算机是player的一个实例。
非常感谢您的帮助!
~ Daan

你能否发布一下你在使用 instanceof 时尝试过的内容? - Romski
如果没有打印输出,那么你可能有其他问题。对于一个Player实例,检查其getClass()的条件不可能评估为false - Marko Topolnik
@Magnilex - 他无法使玩家抽象化,他需要它的实例。 - TheLostMind
4个回答

4

您可以使用 instanceof 来实现此功能:

if(!(player1 instanceof Computer))

...但这是一个糟糕的设计。由于计算机是一个玩家(继承),它们应该拥有相同的能力(API)。一个非常简单的想法是让它们都实现一个 IPlayer 接口,其中包含一个 printGreeting() 方法:

public interface IPlayer {
    void printGreeting();
}

public class Player implements IPlayer {
    private String name;

    public Player(String name) {
        this.name = name;
    }

    public void printGreeting() {
        system.out.println('Your turn! (or whatever)');
    }
}

public class Computer extends Player {
    public Computer(String name) {
        super(name);
    }

    @Override
    public void printGeeting() {
        // NO-OP
    }

}

请注意:更有经验的读者仍然会对上述答案感到不满。我试图避免围绕如何将模型与控制台耦合作为通信手段进行更大的讨论,并且真正应该有类似于printGreeting(Player player)这样的方法的东西(ConsoleMessagePrinter?),它可以打印特定于玩家类型的问候语... - Joe Rinehart
我已经尝试使用instanceof,但由于某种原因它说Player是Computer的一个实例。不过我会使用player消息。谢谢大家! - Daan
甚至可以将Player变成一个抽象类,以防某些功能在Human和Computer中具有相同的实现。 - vefthym

0
你可以在Player类中创建一个返回玩家指令的方法。每个子类可以重写getInstructions方法以提供更具体的指示。对于计算机来说,这将是一个空字符串。你可以按照以下方式实现:
public class Player {
    private String name;

    public Player(String name) {
        this.name = name;
    }

    public String getInstructions() {
        return "Instructions";
    }
}

public class Computer extends Player {
    public Computer(String name) {
        super(name);
    }

    @Override
    public String getInstructions() {
         return "";
    }
}

如果指令不为空,你可以直接打印它们。

Player p = new Player("asdf");
Player c = new Computer("qwer");

String instruction = p.getInstruction();
if (!instruction.empty()) {
    System.out.printLine(instruction);
}

instruction = c.getInstruction();
if (!instruction.empty()) {
    System.out.printLine(instruction);
}

当然可以将一个Output Stream传递给getInstruction方法并直接将其写入输出流。这样你就不需要使用if语句了。

0
计算机始终是Player的一个实例,但Player并不总是计算机。请尝试这个方法:
if (!player.instanceof(Computer)) {...}
但请记住,如果您将player1初始化为新的Player,它永远不会成为计算机的实例。因此,如果您想将Player初始化为计算机,则需要使用计算机的构造函数。 以下代码将返回“true”:
Player player1 = new Computer();
System.out.println(player1.instanceof(Computer));

0

这似乎是一个糟糕设计的症状。通常情况下,您不应该检查值的类别。在这种情况下,您可以在Player类中使用布尔值指定玩家是否为人类。

如果您真的想采用这种设计,您需要使用“instanceof”运算符。搜索“java instanceof”以获取更多信息。

编辑:我现在看到您已经尝试了instanceof。为什么要将instanceof与Player类进行比较?难道您不想将其与Computer类进行比较吗?


1
我已经尝试使用 instanceof,但它始终返回 true,因为 ComputerPlayer 的一个实例。 - Marko Topolnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接