如何使相同 class 的两个对象相互通信?

How do I make two objects of the same class communicate /w each other?

我想让两个相同的对象 class 互相“交谈”。

我想按照描述的做,但不知道怎么做,我也没有找到解决方案:

public class Player  {
    boolean initiative;
    static int counter;
    Player () {
        if (counter == 0) {
            initiative = true;
        } else { 
            initiative = false;
        }
        counter++;
    }
    
    setInitiative (boolean switch){
        //problem is here:
        //if switch true, change all other objects to false
        //if switch false do nothing (not the problem ;))
    }
}

    public class Main {
        var player1 = new Player(); //constructs player1.initiative == true
        var player2 = new Player(); //constructs player2.initiative == false

        player2.setInitiative (true); //should change player1.initiative to false
        System.out.print (player1.initiative);
    }

Outputs>>> false

那么我的 setInitiative 方法必须如何查看才能给我结果? 有没有办法同时与 class 的所有实例通信?

您的问题询问如何 link 相同 class 的两个实例,它还询问如何 link 相同 class 的所有实例。有几种方法可以完成这两种操作,所以我将建议一种简单的方法来完成这两种操作,然后稍微更改设计以简化。

链接两个实例

public class Main {
    public static void main(String[] args) {
        Player player1 = new Player();
        Player player2 = new Player();

        player2.setInitiative(true);
        System.out.print (player1.initiative);
    }
}

class Player  {
    Player linkedPlayer;
    boolean initiative;
    static int counter;
    
    Player () {
        if (counter == 0) {
            initiative = true;
        } else { 
            initiative = false;
        }
        counter++;
    }
    
    static void linkPlayers(Player a, Player b) {
        a.linkedPlayer = b;
        b.linkedPlayer = a;
    }
    
    void setInitiative (boolean newInitiative) {
        initiative = newInitiative;
        if (linkedPlayer != null) {
            linkedPlayer.initiative = !newInitiative;
        }
    }
}

这有一些缺点:

  • 实例必须在创建后 linked。
  • 您必须更改三人游戏的程序结构。

链接所有实例

我不知道如何发现 class 的所有实例,但您可以在创建它们时将它们添加到列表中。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Player player1 = new Player();
        Player player2 = new Player();
        Player player3 = new Player();

        player2.takeInitiative();
        System.out.println(player1.initiative);
        System.out.println(player2.initiative);
        System.out.println(player3.initiative);
    }
}

class Player  {
    private static List<Player> allPlayers = new ArrayList<>();
    
    boolean initiative;
    
    Player () {
        initiative = allPlayers.isEmpty();
        allPlayers.add(this);
    }
    
    void takeInitiative () {
        for (Player p : allPlayers) {
            p.initiative = false;
        }
        initiative = true;
    }
}

我已经更改了设置主动方法。如果有两个以上的玩家,则不清楚当玩家失去主动权时会发生什么。是其他人得到了,还是没有人得到。

代码可能看起来更清晰,但实际上,静态列表存在重大设计问题:

  • 它会阻止您的程序轻松包含一组以上的玩家(可能 运行 同时进行多个游戏)。
  • 它可以防止任何玩家被垃圾收集器清理,因为列表将始终有一个引用。您可以通过某种弱引用来缓解这种情况,但我更愿意解决设计问题。

让我们从玩家 class 中取出所有聪明的逻辑并将其放入游戏 class。

import java.util.*;

public class Game {
    public static void main(String[] args) {
        Player player1, player2, player3;
        
        List<Player> allPlayers = new ArrayList<>();
        allPlayers.add(player1 = new Player(true));
        allPlayers.add(player2 = new Player(false));
        allPlayers.add(player3 = new Player(false));

        assignInitiative(player2, allPlayers);
        System.out.println(player1.initiative);
        System.out.println(player2.initiative);
        System.out.println(player3.initiative);
    }
    
    static void assignInitiative(Player takingInitiative, List<Player> allPlayers) {
        for (Player p : allPlayers) {
            p.setInitiative(false);
        }
        takingInitiative.setInitiative(true);
    }
}

class Player  {
    boolean initiative;
    
    Player (boolean initiative) {
        this.initiative = initiative;
    }
    
    void setInitiative (boolean newInitiative) {
        initiative = newInitiative;
    }
}

在这里,玩家 link 完成了游戏 class。您保留了所有功能,但现在您可以在同一个程序中运行多个游戏并修复了内存泄漏问题。

但由于逻辑已转移到游戏中 class,您可以使用变量进一步简化以保持玩家的主动性。

public class Game {
    public static void main(String[] args) {
        Player player1 = new Player();
        Player player2 = new Player();
        Player player3 = new Player();
        
        Player initiativeHolder = player2;

        System.out.println(player1 == initiativeHolder);
        System.out.println(player2 == initiativeHolder);
        System.out.println(player3 == initiativeHolder);
    }
}

class Player  {
}