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

Odpowiedz Nowy wątek
2018-09-04 21:20

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

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.

Pozostało 580 znaków

2018-09-04 22:14

Rejestracja: 5 lat temu

Ostatnio: 2 godziny temu

0

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

Pozostało 580 znaków

2018-09-04 22:35

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

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

Pozostało 580 znaków

2018-09-04 22:39

Rejestracja: 3 lata temu

Ostatnio: 13 godzin temu

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.

Pozostało 580 znaków

2018-09-04 22:44

Rejestracja: 3 lata temu

Ostatnio: 13 godzin temu

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.

edytowany 2x, ostatnio: vakil, 2018-09-04 22:46

Pozostało 580 znaków

2018-09-05 10:03

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

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)

Pozostało 580 znaków

2018-09-05 15:42

Rejestracja: 3 lata temu

Ostatnio: 2 tygodnie temu

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");.

@wyebani: pole user w klasie UserModel posiada widoczność package-private, tzn. jest dostępne w klasie Main jeżeli obie klasy znajdują się w tym samym package'u. - Kermii 2018-09-05 22:48

Pozostało 580 znaków

2018-09-05 19:59

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

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.

Pokaż pozostałe 4 komentarze
Szczerze to nie wiem co ten playerModel robi... - wyebani 2018-09-05 21:29
Według mojego zamysłu miał zwracać player który został utworzony w PlayerModel. - Pisany 2018-09-05 21:33
Poczytaj o wzoru projektowym builder. Skoro ustawiasz wartości w metodzie void createPlayer() to zmień zwracany typ z void na Player i na końcu metody dodaj return player. A w metodzie initialize zrob this.player = PlayerBuilder().createPlayer(); - wyebani 2018-09-05 21:44
Musiałbym uczynić createPlayer statycznym żeby wywołać bez obiektu, za pomocą klasy. Zresztą nie chce dwa razy aktualizować bazy. Nie zrozumiemy się. - Pisany 2018-09-05 21:57
A to niby dlaczego statyczne? Wydaje mi się, że nie znasz kompletnych podstaw i stąd twój problem. - wyebani 2018-09-06 06:24

Pozostało 580 znaków

2018-09-05 23:08

Rejestracja: 6 lat temu

Ostatnio: 1 miesiąc temu

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.

edytowany 1x, ostatnio: Kermii, 2018-09-05 23:08
Jeśli chodzi o ostatni fragment to po od komentowaniu pierwszej linii z player.getName dostaje null, natomiast pierwszy fragment kodu "Tworzysz obiekt A poza klasami" poza A,B,C ? klasie innej, innej zupełnie? Muszę do tego na świeżo podejść. - Pisany 2018-09-05 23:53
Dodaj w klasie TopMenuIconsController coś takiego: public Player player = new Player(); NullPointer zniknie. - wyebani 2018-09-06 06:25
@wyebani: zniknie, ale to nie jest rozwiązanie którego autor szuka. @Pisany musisz przypisac wartość do player getterem. Najlepiej jak właśnie do tego podejdziesz od nowa na jakimś prostym przykładzie, możesz tworzyć A B i C w zupełnie innej klasie D i potem przekazujesz w jakiś sposób obiekt A do B i C. Co jest tutaj ważne bardzo, a może masz z tym problem klasa to nie obiekt, klasa to pewna definicja struktury obiektu i funkcji, ale możesz mieć dwa RÓŻNE obiekty tej samej klasy. - Kermii 2018-09-06 08:57
No tak o tym mówimy od początku. To są różne obiekty więc jeśli i w jednej klasie i w drugiej ma być referencja na ten sam obiekt to musisz ją przekazać. Chyba nie ma innej opcji :) - wyebani 2018-09-06 09:02
Można stworzyć singletona, ale może lepiej krok po kroku :) - Kermii 2018-09-06 09:13
A czy to podejście z user i userModel jest nieprawidłowe? Tylko że po przeniesieniu do projektu nie działało. - Pisany 2018-09-06 09:31

Pozostało 580 znaków

2018-09-06 09:19

Rejestracja: 3 lata temu

Ostatnio: 2 tygodnie temu

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.

W zamyśle PlayerModel ma pośredniczyć między SqLite a javaFx - Pisany 2018-09-06 09:35

Pozostało 580 znaków

2018-09-06 10:35

Rejestracja: 1 rok temu

Ostatnio: 1 rok temu

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: [email protected]
userModel: [email protected]

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
[email protected]
Jan

User z TOP przed
null

User z TOP po
[email protected]

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.

edytowany 2x, ostatnio: Pisany, 2018-09-06 10:46
Reasumując, jeśli w klasie A masz obiekt klasy C i w klasie B masz obiekt klasy C i chcesz żeby w klasie A i B obiekty klasy C to były te same obiekty, to musisz je przekazać np. W konstruktorze bądź ustawić setterem albo przemyśleć bo może to co wymyśliłem jest bez sensu - wyebani 2018-09-06 10:59
po prostu w klasie TopMenuIcon potrzebne mi są składowe obiektu którym już nadałem wartość w PlayerModel - Pisany 2018-09-06 11:05
No to do metody, w której potrzebujesz tych wartości przekaż ten obiekt (lub konkretną, potrzebna wartość tego obiektu) lub przekaż ten obiekt do klasy (konstruktor lub setter). - wyebani 2018-09-06 11:35
No to ja wiem że muszę ale sęk w tym że mam problem bo mi to nie wychodzi. - Pisany 2018-09-06 11:37
Brute force tutaj nic nie da, wrzucasz różne wersje kodu nie rozumiejąc co on robi. Dostałeś w temacie kilka poprawnych odpowiedzi na swój problem, teraz go przeanalizuj i przestudiuj proste przypadki. Prawdopodobnie jeszcze z 10x wrzucisz kod aż w końcu się Tobie uda, ale dalej tego nie zrozumiesz. To są naprawdę podstawy, więc spróbuj to ogarnąć. - Kermii 2018-09-06 14:44

Pozostało 580 znaków

Odpowiedz

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