如何使用这样的Java接口?

如何使用这样的Java接口?,java,interface,bukkit,Java,Interface,Bukkit,我正在编写一个程序,我想使用接口。类似于Bukkit在他们的玩家课程中使用的方式。我已经多次观看和阅读关于接口的教程,甚至尝试自己测试,但都没有成功 假设我有一个用户界面,带有一个返回字符串的方法占位符。该方法将命名为getName 我想做什么 User user = (INSTANTIATE SOMEHOW); System.out.println(user.getName()); 这在Bukkit的实现中也是以同样的方式实现的 Player player = Server.getPlaye

我正在编写一个程序,我想使用接口。类似于Bukkit在他们的玩家课程中使用的方式。我已经多次观看和阅读关于接口的教程,甚至尝试自己测试,但都没有成功

假设我有一个用户界面,带有一个返回字符串的方法占位符。该方法将命名为getName

我想做什么

User user = (INSTANTIATE SOMEHOW);
System.out.println(user.getName());
这在Bukkit的实现中也是以同样的方式实现的

Player player = Server.getPlayer("Jimmothy");
System.out.println(player.getName());
我就是不知道怎样才能让这样的东西发挥作用。为了实例化player类,可以使用许多getPlayer方法之一。唯一的问题是,包含这些方法的类也是接口,所以我也不知道如何获取接口的实例。搜索代码也无济于事,因为我似乎无法找到这些类中的方法在何处以及是否确实是使用重写或其他方法构建的。如果覆盖就是这样工作的

谁知道呢,也许我只需要知道如何实例化或获取用户界面的实例,我已经准备好了。我知道不能使用新的类名创建接口实例;我从来没有真正理解过他们,但我真的很想


这似乎是一个非常愚蠢的问题,我相信答案很简单,但帮助会很好感谢您的阅读。

祝贺您,您找到了一份工作!让我们直接跳到代码

Test.java:

如您所见,Server类有一个静态方法,该方法将UserImpl的实例作为User类型返回。这是工厂法

这似乎是一个不必要的复杂问题,但它有一个关键的优点:它将某个具体类的使用与其实现的接口分离。这允许更大的灵活性:

它隐藏了实现,因此您可以在多个不同的实现之间自由切换,只要它们都实现了用户界面。从外面看,它们看起来都一样

它允许您在每次请求某个名称时实现池化,并为您提供相同的实例或任何其他分配策略

它使您可以控制对象的创建。您可以执行,例如,检查

如果提供了工厂方法,则不应使用new实例化对象。如果您真的需要,您必须寻找该接口的实现。例如,PlayerImpl:

同样,PlayerImpl也不是这样使用的。

Bukkit在CraftBukkit DMCA中实现服务器。该单例被传递给Bukkit,您可以使用Bukkit.getServer通过API检索该单例。但是,您对ServergetPlayerString方法的工作方式感兴趣

在CraftServer中,它具体实现了getPlayerString方法,它从玩家的名字中检索玩家。服务器中的播放器存储在一个集合表中,其名称/UUID为实际播放器,由CraftPlayer实现。每次玩家加入时,都会实例化一个新的玩家并将其放入集合中

因此,要自己完成这项工作,您必须实现检索接口和要检索的实际对象。实质上:

interface Player {
    void kick(String message);
}

class CraftPlayer implements Player {
    @Override public void kick(String message) {
        // Implementation
    }
}

interface Server {
    Player getPlayer(String name);
}

class CraftServer implements Server {
    private final Map<String, Player> players = new HashMap<>();

    public CraftServer() {
        Bukkit.setServer(this);
    }

    @Override public Player getPlayer(String name) {
         return players.get(name);
    }

    public void joinPlayer(String name) {
        Player p = new CraftPlayer();
        players.put(name, p);
    }
}

class Bukkit {
    private Server server;
    public void setServer(Server server) {
        if (server == null) this.server = server;
    }

    public Server getServer() {
        return server;
    }
}

// Usage
new CraftServer();
Player p = Bukkit.getServer().getPlayer("Name");
if (p == null) {
    // Not online
    System.out.println("No player with that name is online");
    return;
}
p.kick("lol");

查看反射。接口就是断言类具有某些方法/字段。假设您有一个类ActualUser实现用户,那么您可以编写如下内容:User u=new ActualUser;。它就像引用子类的超类的引用。无法创建接口本身的实例,因为接口没有构造函数。Java中的接口是用来替代Java中无法实现的多重继承的其他东西之一。我想我现在明白了。那么这些getPlayer方法返回的是一个实现Player接口的类?不,它不是工厂方法!这是因为获取播放器不一定构成新的实例化。谁说工厂方法每次@xTrollxDudex都必须返回一个新实例?我甚至在列表的第2点说了相反的话。public static Player getPlayerString name{return new PlayerImplname;}你的例子说明了另一种情况,这是一般情况下最简单的例子,在下面的讨论中有详细说明。同样,清单的第2点。在这两种情况下,它仍然是一个工厂方法@xTrollxDudex。我真的看不出你评论的要点。。。不确定是拖拉还是严重的…工厂方法处理创建对象的问题。我不是直接引用你的消息来源。我建议您自己阅读实际的实现代码。。。。。。。。。
Player foo = new PlayerImpl("foo");
interface Player {
    void kick(String message);
}

class CraftPlayer implements Player {
    @Override public void kick(String message) {
        // Implementation
    }
}

interface Server {
    Player getPlayer(String name);
}

class CraftServer implements Server {
    private final Map<String, Player> players = new HashMap<>();

    public CraftServer() {
        Bukkit.setServer(this);
    }

    @Override public Player getPlayer(String name) {
         return players.get(name);
    }

    public void joinPlayer(String name) {
        Player p = new CraftPlayer();
        players.put(name, p);
    }
}

class Bukkit {
    private Server server;
    public void setServer(Server server) {
        if (server == null) this.server = server;
    }

    public Server getServer() {
        return server;
    }
}

// Usage
new CraftServer();
Player p = Bukkit.getServer().getPlayer("Name");
if (p == null) {
    // Not online
    System.out.println("No player with that name is online");
    return;
}
p.kick("lol");