Что заставляет поле объекта автоматически меняться? - PullRequest
0 голосов
/ 05 февраля 2020

Я делаю простую систему Player / Session, но я только что обнаружил ошибку logi c, даже если мне кажется, что все в порядке.

Позвольте мне описать мою идею, я Я все еще изучаю, как работает OOP, поэтому я тренируюсь в этом проекте:

  • Прежде всего я создал два класса:
    1. Класс игроков
  • Класс Session

В классе Session у меня есть метод joinSession (Session s); Этот метод заставит объект игрока присоединиться к сеансу следующим образом:

Session s1 = new Session();
Player p1 = new Player(name : "Jack");

p1.joinSession(s1);

Проблема в том, что в атрибутах сеанса у меня есть:

public Player firstPlayerToJoin;
public Player lastPlayerToJoin;

Всякий раз, когда я заставляю игрока присоединиться к Сессия все вроде бы хорошо, Джек: firstPlayerToJoin и lastPlayerToJoin. Но реальная проблема заключается в том, что другой игрок решит присоединиться, например:

Player p2 = new Player("Rose");    
p2.joinSession(s1);

Роза снова будет firstPlayerToJoin и lastPlayerToJoin, а не будет lastPlayerToJoin.

Вот мой код:

Первый класс игрока



    private static int id;

    private Session session;

    boolean isOnSession = false;

    public static String name;

    public static void say(String message){
        System.out.println(name + " says " + message);
    }

    // Player join session

    public void joinSession(Session s){
        this.session = s;
        System.out.println(name + " joined the session : " + this.session.sessionName );

        System.out.println("Players ONLINE = " + s.playersOnline);
        if( s.playersOnline == 0){
            s.firstPlayerToJoin = this;
            s.lastPlayerToJoin = this;
        }  else {

        s.lastPlayerToJoin = this;}
        s.playersOnline++;
    }


    public void quitSession(){
        this.session = null;
        isOnSession = false;
        System.out.println(name + " left his session.");
    }

    Player(String name){
        id = id++;
        this.name = name;

    }

    public static void showPlayerInfo(Player n){
        System.out.println("========== Player INFO ==========");
        System.out.println("ID : " + id + "\nName : " + name );
    }
}

Вот класс сеанса:


public class Session {

    int id = 0;

    int maxConnected = 10;

    public int playersOnline = 0;

    String[] playersConnected = new String[maxConnected];

    public String sessionName;
    public Player firstPlayerToJoin;
    public Player lastPlayerToJoin;

    Session(){
        this.id=id++;

this.sessionName = "SESSION"+id;
    }

    public void sessionInfo(){
        System.out.println("======== Session INFO ========");
        System.out.println("Session name : " + sessionName);
        System.out.println("Players online : " + playersOnline);
        System.out.println("First player to join : " + firstPlayerToJoin.name);
        System.out.println("Last player to join : " + lastPlayerToJoin.name);
        System.out.println("==============================");
    }

    int getPlayersOnline(){
        return this.playersOnline;
    }
}

И, наконец, основной класс и метод:


public class Main {

    public static void main(String[] args) {


Player p1 = new Player("Omar");

Session s1 = new Session();

p1.joinSession(s1);

s1.sessionInfo();


Player p2 = new Player("Rick");

p2.joinSession(s1);

s1.sessionInfo();




    }



}

Если есть вопросы или путаница в идее, дайте мне знать.

Фактический результат:

Omar joined the session : SESSION0
Players ONLINE = 0
======== Session INFO ========
Session name : SESSION0
Players online : 1
First player to join : Omar
Last player to join : Omar
==============================
Rick joined the session : SESSION0
Players ONLINE = 1
======== Session INFO ========
Session name : SESSION0
Players online : 2
First player to join : Rick
Last player to join : Rick
==============================

В строке непосредственно перед последней, которую мы можем видеть: Первый игрок, который присоединится: объект игрока Рика p1 переопределяет атрибут, даже если есть условие, которое не соответствует действительности.

1 Ответ

1 голос
/ 05 февраля 2020

Я собираюсь уточнить комментарий RealSkepti c (который я не выяснил, пока он не сказал это).

У вас есть ваше поле имени как stati c. В настоящее время, если бы вы написали (p1 == p2), вы бы получили false, потому что это действительно разные объекты. Делая эту переменную stati c, вы устанавливаете ее для всего класса (переменные Stati c называются class переменные). То, что вы намеревались сделать, это локализовать вашу переменную так, чтобы ваши отдельные игроки имели свои собственные имена.

Поэтому:

public static String name;

должно быть:

public String name;

Вероятно, ваша среда IDE сообщает вам, что вы неправильно вводите имя прямо сейчас. При доступе к переменным или методам stati c вы получаете доступ к ним через сам класс, а не через объекты этого класса.

например,

Player.NAME

, а не

Player p1 = new Player("tom");
p1.NAME;

потому что, как уже упоминалось, они предназначены для самого класса, а не для локальных объектов указанного класса. Здесь - дальнейшее чтение, если вы хотите:

...