Odwołanie się w klasie C do obiektu z klasy A utworzonego w klasie B

0

Tak jak w temacie mam dość błahy problem, mianowicie stworzyłem obiekt klasy A w klasie B i potrzebuje go przekopiować lub dostać się do składowych w klasie C.
Każda próba kończy się nullpointerem.
Mógłby ktoś podesłać parę linijek jak by to wyglądało z 1 zmienna.

0

A czemu nie możesz obiektu A stworzyć w jakimś miejscu poza klasami B i C i go do nich wstrzyknąć ?

0

Generalnie chodziło mi o coś takiego, liczyłem że mam jakiś zawias ale w tym przykładzie bangla. Coś więcej o wstrzykiwaniu ?

public class Main {


    public static void main(String[] args) {
        UserModel userModel= new UserModel();
        //userModel.addName();
        userModel.user.setName("Jacek");
        User user;
        System.out.println(userModel.user.getName());
        System.out.println(userModel.getUser().getName());
    }
}
public class User {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class UserModel {
    User user = new User();

    public void addName(){
        user.setName("Jan");
    }

    public User getUser(){
        return user;
    }
}
0

Chyba tak to będzie:

class B {
   private A a;
   A getA() {
       return a;
   }
}

class C {
      private A a = null;

     void setA(A a) {
          this.a = a;
     }
}

wywołanie :


A a = new A();
C c = new C();

c.setA(a.getA());

Zadziała jesli wszystkie klasy będą w tym samym pakiecie, jeśli nie to ustaw modyfikatory widoczności na public.

0
Pisany napisał(a):

Generalnie chodziło mi o coś takiego, liczyłem że mam jakiś zawias ale w tym przykładzie bangla. Coś więcej o wstrzykiwaniu ?

public class Main {


    public static void main(String[] args) {
        UserModel userModel= new UserModel();
        //userModel.addName();
        userModel.user.setName("Jacek");
        User user;
        System.out.println(userModel.user.getName());
        System.out.println(userModel.getUser().getName());
    }
}
public class User {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class UserModel {
    User user = new User();

    public void addName(){
        user.setName("Jan");
    }

    public User getUser(){
        return user;
    }
}

Tworzysz obiekt A poza klasami i dodajesz go do konstruktora jako parametr, czyli wstrzykujesz obiekt do środka

np.

A a = new A();

B b = new B(a);
C c  = new C(a);

a w srodku klasy:


class B {
private A a;

   B(A a) {
        this.a = a;
   }
}

Tak samo w klasie C i masz ten sam obiekt w dwóch klasach.

0

Coś jest nie tak otrzymuje 2 różne adresy obiektu.
Zmieńmy przykład może, mam klasy:
Player - zawiera składowe +gettery/settery
PlayerModel - deklaruje i tworze nowy obiekt Player +getPlayer
Controller - deklaruje playerModel i sout(playerModel.getPlayer)

0
Pisany napisał(a):

Generalnie chodziło mi o coś takiego, liczyłem że mam jakiś zawias ale w tym przykładzie bangla. Coś więcej o wstrzykiwaniu ?

public class Main {


    public static void main(String[] args) {
        UserModel userModel= new UserModel();
        //userModel.addName();
        userModel.user.setName("Jacek");
        User user;
        System.out.println(userModel.user.getName());
        System.out.println(userModel.getUser().getName());
    }
}
public class User {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class UserModel {
    User user = new User();

    public void addName(){
        user.setName("Jan");
    }

    public User getUser(){
        return user;
    }
}

Jak ma działać wg Ciebie linia w mainie: userModel.user.setName("Jacek"); ?
Przecież pole User user = new User(); jest domyślnie prywatny więc nie możesz się z maina odwołać bezpośrednio do tego pola.

Jak już to w mainie powinno być userModel.getUser().setName("Jacek");.

0
wyebani napisał(a):

Jak ma działać wg Ciebie linia w mainie: userModel.user.setName("Jacek"); ?
Przecież pole User user = new User(); jest domyślnie prywatny więc nie możesz się z maina odwołać bezpośrednio do tego pola.

Jak już to w mainie powinno być userModel.getUser().setName("Jacek");.

Oby dwa wypisują Jacek sprawdzone, inaczej tego bym nie wrzucał.
Jeszcze raz, tym razem wstawię kod o który mi chodzi. Chciałbym w tej klasie:

public class TopMenuIconsController implements Initializable {
    
    public ImageView avatarTopMenuIcons;
    public Label levelTopMenuIcons;
    public Label cashTopMenuIcons;
    public Label cashInBankTopMenuIcons;
    public Label nameTopMenuIcons;
    public Player player;


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        PlayerModel playerModel=new PlayerModel();
        System.out.println(playerModel.getPlayer());
        System.out.println(player);
        
//        nameTopMenuIcons.setText(player.getName());
//        levelTopMenuIcons.setText(Integer.toString(player.getLevel()));
//        cashTopMenuIcons.setText("100");
//        cashInBankTopMenuIcons.setText("2000");
//        Image image = new Image(String.valueOf(player.getAvatar()));
//        avatarTopMenuIcons.setImage(image);

    }
}

żeby za // linie działały, żeby któryś ze sout zwracał mi taka samą referencje jak System.out.println(player); w klasie PlayerModel.
Player jest stworzony w tej klasie

public class PlayerModel {
     public Player player = new Player();

    public void createPlayer(int id, String name) {
        PlayerDao playerDao = new PlayerDao(DbManager.getConnectionSource());
        player.setId(id);
        player.setName(name);
        player.setLevel(1);
        player.setStrange(8);
        player.setAgility(8);
        player.setCharisma(8);
        player.setIntellect(8);
        playerDao.createOrUpdate(player);
        playerDao.refresh(player);
        DbManager.closeConnectionSource();
        System.out.println("Player w PlayerModel.createPlayer:");
        System.out.println(player);
    }
    public Player getPlayer(){
        return player;
    }
}

Nie rozumiem, porównując do Main, User, UserModel to jest to samo.

0

@Pisany: jeżeli chodzi o ostatni przykład, dlaczego zakomentowałeś kod? Nie pojawia się przypadkiem NullPointerException w pierwszej zakomentowanej linii? W tym przypadku problemem jest to że player nie jest nigdy inicjalizowany, a dlaczego? Bo jest to inny player, niż ten który tworzysz przy okazji tworzenia instancji typu PlayerModel. Obiekty tego samego typu, ale inne wartości.

Ale wracając do sedna, chciałbyś operować w dwóch klasach na tym samym obiekcie. Przykład podany przez @vakil jest poprawny

vakil napisał(a):

Tworzysz obiekt A poza klasami i dodajesz go do konstruktora jako parametr, czyli wstrzykujesz obiekt do środka

np.

A a = new A();

B b = new B(a);
C c  = new C(a);

a w srodku klasy:


class B {
private A a;

   B(A a) {
        this.a = a;
   }
}

Tak samo w klasie C i masz ten sam obiekt w dwóch klasach.

To jest jedno z podejść, spróbuj na takich prostych klasach może najpierw aby to zrozumieć. W tym przypadku jest tworzony obiekt A (nazwijmy go objectA), a następnie przekazywana referencja (adres tego obiektu) do obiektów typu B i C w konstruktorze. Jeżeli teraz implementacja klasy B albo C będzie operować na objectA, to będzie on zmodyfikowany w obu obiektach.

Dobra, a teraz wyeliminujmy w końcu ten błąd który masz w pierwszej zakomentowanej linii. Jak pisałem pole player w klasie TopMenuIconsController jest nullem. Chciałbyś teraz do niego przypisać obiekt stworzony w PlayerModel, więc musisz go przypisać.

player = playerModel.getPlayer();

takim o to cudem możesz odkomentować pierwszą linię, z kolejnymi bym się wstrzymał bo znowu natrafisz na NPE.

0

Ja w klasie Player stworzylbym wewnętrzna klasę PlayerBuilder (skoro autor potrzebuje buildera) i w ten sposób tworzył obiekt, bez jakiejś dziwnej klasy PlayerModel, która w zasadzie nic nie robi.

0
vakil napisał(a):

Tworzysz obiekt A poza klasami i dodajesz go do konstruktora jako parametr, czyli wstrzykujesz obiekt do środka

np.

A a = new A();

B b = new B(a);
C c  = new C(a);

a w srodku klasy:


class B {
private A a;

   B(A a) {
        this.a = a;
   }
}

Tak samo w klasie C i masz ten sam obiekt w dwóch klasach.

public class User {
    
    private int id;
    private String name;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


public class UserModel {

    private User user;

    public UserModel(User user){
        this.user= user;
    }

}


public class Main {

    public static void main(String[] args) {
        User user= new User();
        user.setName("JAN");
        System.out.println(user.getName());

        UserModel userModel=new UserModel(user);
        System.out.println("user: "+user);
        System.out.println("userModel: "+userModel);
    }
}

JAN
user: User@48140564
userModel: UserModel@58ceff1

vakil napisał(a):

Chyba tak to będzie:

class B {
   private A a;
   A getA() {
       return a;
   }
}

class C {
      private A a = null;

     void setA(A a) {
          this.a = a;
     }
}

wywołanie :


A a = new A();
C c = new C();

c.setA(a.getA());

Zadziała jesli wszystkie klasy będą w tym samym pakiecie, jeśli nie to ustaw modyfikatory widoczności na public.

public class User {

    User(String name){
        this.name=name;
    }

    private int id;
    private String name;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class UserModel {

    User user=new User("Jan");

    User getUser(){
        return user;
    }
}
public class Top {
    User user=null;

    void setUser(User user){
        this.user=user;
    }
    User getUser(){
        return user;
    }

    void writeTopUser(){
        System.out.println(user);
    }
}
public class Main {

    public static void main(String[] args) {
        UserModel userModel= new UserModel();
        Top top = new Top();

        System.out.println("User z userModel");
        System.out.println(userModel.getUser());
        System.out.println(userModel.getUser().getName()+"\n");

        System.out.println("User z TOP przed ");
        System.out.println(top.getUser()+"\n");

        System.out.println("User z TOP po");
        top.setUser(userModel.getUser());
        System.out.println(top.getUser());
    }
}

User z userModel
User@75412c2f
Jan

User z TOP przed
null

User z TOP po
User@75412c2f

Czyli działa tak jak bym chciał ^ ^
Reasumując nie ważne w jakiej klasie stworze obiekt "a" ale musi tam być getter do "a" , a nie w klasie A. Tak ?

EDIT

Nie działa w głównym

public class PlayerModel {

    public Player player= new Player();

    public void createPlayer(int id, String name) {...}

    public Player getPlayer() {
        return player;
    }
}
public class TopMenuIconsController implements Initializable {

    public ImageView avatarTopMenuIcons;
    public Label levelTopMenuIcons;
    public Label cashTopMenuIcons;
    public Label cashInBankTopMenuIcons;
    public Label nameTopMenuIcons;
    Player player=null;
    PlayerModel playerModel = new PlayerModel();
    

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        setPlayer(playerModel.getPlayer());
        System.out.println("Player w topMenu");
        System.out.println(player);


//        nameTopMenuIcons.setText(player.getName());
//        levelTopMenuIcons.setText(Integer.toString(player.getLevel()));
//        cashTopMenuIcons.setText("100");
//        cashInBankTopMenuIcons.setText("2000");
//        Image image = new Image(String.valueOf(player.getAvatar()));
//        avatarTopMenuIcons.setImage(image);

    }

    public void setPlayer(Player player) {
        this.player = player;
    }
}

Zdaje się że zrobiłem wszystko tak samo poza jednym. wywołałem setPlayer(playerModel.getPlayer()); bez utworzenia nowego obiektu TopMenuIconsControlle, po utworzeniu dostaje masę błędów z initialize.

0

Dobra, mam to na konstruktorach. Dzięki wielkie wszystkim, za pomoc jak i krytykę. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1