简体   繁体   中英

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

i want to make two objects of the same class "talk" to each other.

I want to do as described, but don't know how and i didn't find a solution:

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

so how does my setInitiative method have to look, to give me my results? is there a way to communicate with all instances of a class at once?

Your question asks how to link two instances of the same class and it also asks how to link all instances of the same class. There are several ways of doing both of these so I am going to suggest one simple way way of doing each, and then change the design a little to simplify.

Linking two instances

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;
        }
    }
}

This has a few disadvantages:

  • Instances have to be linked after creation.
  • You would have to change the structure of the program for a three player game.

Linking all instances

I don't know a way of discovering all the instances of a class but you could add them to a list when you create them.

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;
    }
}

I have changed the set Initiative method. With more than two players, it is unclear what happens when a player loses initiative. Does somebody else get it, or does nobody have it.

The code may look cleaner but actually, there are significant design problems with the static list:

  • It stops your program from easily containing more than one set of players (maybe running multiple games at the same time).
  • It prevents any player from being cleaned up by the garbage collector as the list will always have a reference. You could mitigate this with some sort of weak reference but I would prefer to fix the design problem.

Let's take all of the clever logic out of the player class and put it into a game 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;
    }
}

Here, the Player are linked through the game class. You have kept all the functionality but now you could have multiple games in the same program and have fixed the memory leak.

But since the logic has moved to the game class, you could simplify even further with a variable to hold the player with initiative.

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  {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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