Problem z współdziałąniem funkcji

Problem z współdziałąniem funkcji
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0

Dodałem sobie rzeczy do sejfu za pomocą listy i w funkcji add() jestem w stanie je odczytać, ale nie potrafię ich odczytać za pomocą funkcji printContent() no i połączyć tego z toString w klasie Thing.
To pewnie bardzo proste, ale ja nie mam jeszcze takiej biegłości w tym. Pewnie analogiczne byłoby stworzenie funkcji kasującej jakiś element z listy, ale wtedy i jej efekt trzeba by było jakoś połączyć z funkcją zwracającą ostateczną zawartość listy.
Czy mógłbym prosić o jakieś rozjaśnienie mojego przyćmionego umysłu?

Kopiuj
import java.util.ArrayList;

class Safe {
    double weight;
    double volume;
    double maxWeight;
    double maxVolume;

    public Safe(double weight, double volume, double maxWeight, double maxVolume){
        this.weight = weight;
        this.volume = volume;
        this.maxWeight = maxWeight;
        this.maxVolume = maxVolume;
    }
    public void add(Thing thing) {
        ArrayList<String> item_name = new ArrayList<String>();
        item_name.add(thing.getName());
        ArrayList<Double> item_weight = new ArrayList<Double>();
        item_weight.add(thing.getWeight());
        ArrayList<Double> item_volume = new ArrayList<Double>();
        item_volume.add(thing.getVolume());

        for (int i = 0; i < item_name.size(); i++) {
            System.out.println(item_name.get(i));
            System.out.println(item_weight.get(i));
            System.out.println(item_volume.get(i));
        }
    }
    public Thing remove(int index) {
}

    public void printContent(){
    }
}

class Thing {
    protected double weight;
    protected double volume;
    protected String name;

    public Thing(String name, double weight, double volume){
        if(name != null)
            this.name = name;
        else
            this.name = "";
        this.weight = Math.max(weight, 0.0);
        this.volume = Math.max(volume, 0.0);
    }

    public double getWeight(){
        return weight;
    }

    public double getVolume(){
        return volume;
    }
    public String getName(){
        return name;
    }
    @Override
    public String toString() {
        return name + " (" + weight + " kg, " + volume + " l)";
    }
}

class Box extends Thing {
    protected double height;
    protected double width;
    protected double depth;

    public Box(String name, double weight,
               double height, double width, double depth){
        super(name, weight, height*width*depth*1000);
        this.height = height;
        this.width = width;
        this.depth = depth;
    }
    public double getHeight(){
        return height;
    }
    public double getWidht(){
        return width;
    }
    public double getDepth(){
        return depth;
    }
}
public class safe1{
    public static void main(String args[]){
        Safe subject = new Safe(0.100, 0.5, 40, 50);
        subject.add(new Thing("Ball", 1, 3));
        subject.add(new Thing("Torch", 0.5, 1));
        subject.add(new Box("Box1", 5, 0.1,0.5,0.5));
        subject.printContent();
//        subject.remove(2);     //to bylby drugi element z listy
    }
}

edytowany 1x, ostatnio: geoinfomat
ZI
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 8 godzin
  • Postów:230
0

Masz listy w metodzie a nie w klasie.
W skrocie. Wchodzis w metoda -> tworzysz liste -> dodajesz obiekt -> wychodzisz z metody -> twoja lista to zmienan lokalna wiec jest usuwana
Stworz liste w klasie i do niej dodawaj :)

edytowany 1x, ostatnio: Ziemiak
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0
Ziemiak napisał(a):

Masz listy w metodzie a nie w klasie.
W skrocie. Wchodzis w metoda -> tworzysz liste -> dodajesz obiekt -> wychodzisz z metody -> twoja lista to zmienan lokalna wiec jest usuwana
Stworz liste w klasie i do niej dodawaj :)

Bardzo dziękuję za uwagę.
Zrobiłem więc coś takiego w klasie Backpack:

Kopiuj
ArrayList<Thing> item = new ArrayList<Thing>();

    public void add(Thing thing) {
        item.add(thing);
    }

    public void printContent(){
        System.out.println(new Thing(Backpack.class.getSimpleName(), this.weight, this.volume) + " with");
        System.out.println();
        for (int i=0;i<item.size();i++) {
            System.out.print((i+1) + ": ");
            System.out.println(item.get(i));
        }
        System.out.println("Total: ");
    }

I wszystko mi się już nawet wyświetla, ale teraz chciałbym policzyć łączny ciężar i objętość wraz wagą i objętością samego pudełka. Czy to się da jakoś wyciągnąć? Podejrzewam, że z listy to chyba nie, więc pewnie z klasy Thing, ale jak?
Tak sobie myślę, że powinienem wagę i objętość pudełka dołożyć jakoś na początek listy, to wtedy łatwiej byłoby z jednego miejsca wyciągnąć te parametry, Ale na ten moment mam za mało umiejętności. Czy mógłbym prosić o pomoc?

edytowany 2x, ostatnio: geoinfomat
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

W pierwotnym kodzie nie ma klasy `Backpack'. Zmieniłeś nazwę, czy dopisałeś nową klasę?


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0
bogdans napisał(a):

W pierwotnym kodzie nie ma klasy `Backpack'. Zmieniłeś nazwę, czy dopisałeś nową klasę?

Oj tak, sejf i plecak to to samo...

CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:3 dni
  • Postów:296
0
Kopiuj
class Backpack{
...
public double getWeight(){
        double total = 0;
	for (int i=0;i<item.size();i++) {
            total += item.get(i).getWeight();
        }
        return total;
    }
}

W kolekcji masz obiekty typu Thing, które mają gettery: getWeight(), getVolume() więc korzystaj z nich.

GE
To jest dziwne, że mam nawet taką samą metodę (jedyne, co się różni to sum zamiast total, ale wczoraj widocznie miałem zły dzień i mi to nie działało. Dziś działa i rzeczywiście sumuje, dziękuję. Zastanawiam się jeszcze tylko jak dodać wagę samego plecaka(sejfu), ale może coś uda mi się wymyślić. Już siadam do kodu :)
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Może tak:

Kopiuj
        double totalWeight = 0.0;
        for (int i=0;i<item.size();i++) {
            System.out.print((i+1) + ": ");
            Thing thing = item.get(i);
            System.out.println(thing);
            totalWeight += thing.weight;
        }

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
GE
Hmm, kiedy ja się nauczę tak pisać... Super!
bogdans
Jak dożyjesz moich lat ;)
CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:3 dni
  • Postów:296
0

@bogdans Czy uważasz, że lepiej odwoływać się do pola czy do gettera? Wg mnie lepiej korzystać z getterów, przykład może naciągany, ale ilustruje tę różnicę:

Kopiuj
class Person{
  protected String name;
  public Person(String name){
    this.name = name;
  }

  public Person(){
  }

  public String getName(){
    return name;
  }
}
class Worker extends Person{
  protected char[] name;
  public Worker(char[] name){
    this.name = name;
  }

  public String getName(){
    return new String(name);
  }
}

class Main {
  public static void main(String[] args) {
    Person p = new Worker("Adam".toCharArray());
    System.out.println(p.getName());
    System.out.println(p.name);
  }
}

Efekt:
Adam
null

edytowany 1x, ostatnio: cs
bogdans
Nie uważam, że jedynie słuszne stanowisko, to: zawsze gettery/zawsze pola, o ile są widoczne (niepotrzebne skreślić). Ale powyższy przykład jest wg mnie przykładem na wyższość pól. Wyjście null jest sygnałem dla programisty, że definicje klas są zapewne niewłaściwe.
CS
Chodziło mi o to, że jeśli w klasach z jakiś powodów są gettery, to trzeba z nich korzystać, jeśli by ich nie było to sygnał, że odczytujemy pola. A null, nie jest sygnałem, że coś nie tak, tylko że klasa jest niekonsekwentna, daje możliwość odczytania pól i są gettery, więc po przykryciu (celowym) odczyt z pola daje null'a.
DQ
  • Rejestracja:prawie 10 lat
  • Ostatnio:7 miesięcy
  • Postów:141
0
cs napisał(a):

@bogdans Czy uważasz, że lepiej odwoływać się do pola czy do gettera? Wg mnie lepiej korzystać z getterów, przykład może naciągany, ale ilustruje tę różnicę:

Kopiuj
class Person{
  protected String name;
  public Person(String name){
    this.name = name;
  }

  public Person(){
  }

  public String getName(){
    return name;
  }
}
class Worker extends Person{
  protected char[] name;
  public Worker(char[] name){
    this.name = name;
  }

  public String getName(){
    return new String(name);
  }
}

class Main {
  public static void main(String[] args) {
    Person p = new Worker("Adam".toCharArray());
    System.out.println(p.getName());
    System.out.println(p.name);
  }
}

Efekt:
Adam
null

Na siłę to można wszystko udowodnić. Ten przykład ma tyle złych praktyk, że nie ma sensu go rozpatrywać. Jednym z sensowniejszych podejść jest zapewnienie niemutowalności danego pola i odwoływanie się bezpośrednio do niego. W każdym innym przypadku wpierw należy zastanowić się czy getter w ogóle jest potrzebny. W ten sposób możesz łatwo ujawnić wewnętrzny stan danego obiektu narażając go na modyfikację z zewnątrz, a tym samym trudne do określenia błędy

CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:3 dni
  • Postów:296
0

@DisQ: Obrażasz się na możliwości Javy, nie ja wymyśliłem przykrywanie pól. Wg Ciebie złą praktyką jest robienie pól, które nie są final? Jak w tym przykładzie zmienisz getterem pola name? Była moda na gettery i settery, teraz na bezkrytyczne wciskanie niemutowalności, gdzie tylko się da. Jedno i drugie ma swoje miejsce. Wszyscy patrzą na Jave przez pryzmat webówki, jako jedynie słusznego zastosowania.

DQ
  • Rejestracja:prawie 10 lat
  • Ostatnio:7 miesięcy
  • Postów:141
0

Daleko mi do obrażania się na Javę. Tak, według mnie jeśli tylko można to powinno się robić pola final - mi to ułatwia pisanie kodu, a co ważniejsze - jego czytanie. W twoim przykładzie po prostu bym nie zmieniał pola name, a tym bardziej nie używałbym do tego celu gettera.

CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:3 dni
  • Postów:296
0

@DisQ: @geoinfomat uczy się, jak widać, Javy i działa z dziedziczeniem, więc pokazałem możliwe skutki tego dziedziczenia i różnicę między getterem a odwoływaniem się do pól. Nie korzysta z final, więc może jeszcze tego nie zna, nie przerabiał, trudno wszystko na raz ogarnąć, więc zasymulował niezmienność pola samymi getterami. W kodzie wszystko robi w jednym pliku, w dodatku w tym samym pakiecie, więc i tak te gettery są zbędne. Ale jak skorzysta z klas w innym pakiecie to nie dostanie się do pól, więc lepiej żeby korzystał z utworzonych getterów i pól protected, niż robił publiczne pola bez final.

GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0

Zdaję sobie sprawę z tego, że rozmowy na tym forum są na znacznie wyższym poziomie. Wszystko uważnie czytam. Dochodzę jednak do wniosku, że bez prób niewiele mi się uda osiągnąć.
Ja dalej jestem na etapie wkładania do sejfu różnych rzeczy.
Włożyłem już do niego nawet kolejny sejf, ale jak wynika z main, powinienem do tego drugiego sejfu włożyć inne przedmioty (te jednak mają nieco inne rozszerzające pola), no i tu mam znowu kłopot, bo jak na razie wychodzi mi bardziej jakiś adres niż liczby.
Próbowałem założyć nową listę, ot przez analogię, ale wciąż gdzieś popełniam błędy.
Do znudzenia proszę o dalszą pomoc (ale naprawdę nad tym siedzę, tylko umysł już nie ten...)
Wydaje mi się, że nie potrafię wykorzystać tej rozszerzającej klasy Box...
PS. Z grzeczności próbuję wykorzystać jeden i drugi pomysł, a kiedyś pewnie się zastanowię, który lepszy.

Kopiuj
class Safe {
    double weight;
    double volume;
    double maxWeight;
    double maxVolume;


    public Safe(double weight, double volume, double maxWeight, double maxVolume) {
        this.weight = weight;
        this.volume = volume;
        this.maxWeight = maxWeight;
        this.maxVolume = maxVolume;
    }

    ArrayList<Thing> item = new ArrayList<Thing>();
    ArrayList<Safe> item1 = new ArrayList<Safe>();

    public void add(Thing thing) {
        item.add(thing);
    }

    public void add(Safe small) {
        item.add(new Thing(Safe.class.getSimpleName(), small.weight, small.volume ));
    }

    public void remove(int index) {
        item.remove(index - 1);
    }

    public void printContent() {
        System.out.println(new Thing(Safe.class.getSimpleName(), this.weight, this.volume) + " with");
        double totalWeight = 0.0;
        double totalVolume = 0.0;
        for (int i = 0; i < item.size(); i++) {
            System.out.print((i + 1) + ": ");
            Thing thing = item.get(i);
            System.out.println(thing);
            totalWeight += thing.weight;
            totalVolume += thing.volume;
//            for (int j = 0; j < item1.size(); j++) {
//                System.out.print((j + item1.size() + 1) + ": ");
//                Safe small = item1.get(j);
//                System.out.println(small);
//                totalWeight += small.weight;
//                totalVolume += small.volume;
//            }
        }
        System.out.println("Total: " + (totalWeight + this.weight) + ", " + (totalVolume + this.volume));
        System.out.println();
    }

   public double getWeight() {
        double total = 0.0;
        for (int i = 0; i < item.size(); i++) {
            total += item.get(i).getWeight();
        }
        return total+ this.weight;
    }
}

edytowany 1x, ostatnio: geoinfomat
CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:3 dni
  • Postów:296
0

Pomyśl co by Ci dało wyprowadzenie klasy Safe z Thing, wtedy zamiast robić osobną kolekcję na sejfy miałbyś jedną na wszystkie rzeczy, w tym i sejf. Wtedy miałbyś jedną metodę add. Możesz uznać, że na ten moment to wystarczająco "dobre" rozwiązanie", potem jak poznasz interfejsy to zapomnij o tym.

GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0
cs napisał(a):

Pomyśl co by Ci dało wyprowadzenie klasy Safe z Thing, wtedy zamiast robić osobną kolekcję na sejfy miałbyś jedną na wszystkie rzeczy, w tym i sejf. Wtedy miałbyś jedną metodę add. Możesz uznać, że na ten moment to wystarczająco "dobre" rozwiązanie", potem jak poznasz interfejsy to zapomnij o tym.

To może śmieszne, ale trzy dni mi zajęły próby z tą sugestią i nie wymyśliłem niczego sensownego.
Niestety na ten moment nie potrafię umieścić mniejszego sejfu z całą jego zawartością w większym.
Natomiast potrafię utworzyć dwa osobne sejfy z zawartością, tzn wpisując w funkcji main

Kopiuj
b.printContent();
small.printContent();

wyświetla mi się zawartość obu. Niemniej jednak dziękuję Państwu za pomoc. Na razie zabieram się za prostsze rzeczy, żeby później zrozumieć te trudniejsze.
Gdyby jeszcze ktoś zechciał bardziej łopatologicznie mi to wytłumaczyć, to pewnie wrócę do pracy nad tym programem.
Spodziewana zawartość w zadaniu jest taka:
Safe (0.1 kg, 0.5 l) with
1: Ball (1 kg, 3 l)
2: Torch (0.5 kg, 1 l)
3: Box1 (5 kg, 25 l)
Total: 5.6 kg 29.5 l
Safe (0.1 kg, 0.5 l) with
1: Ball (1 kg, 3 l)
2: Box1 (5 kg, 25 l)
Total: 5.1 kg 28.5 l
5.1
Safe (0.1 kg, 0.5 l) with
1: Ball (1 kg, 3 l)
2: Box1 (5 kg, 25 l)
3: Backpack (0.01 kg, 0.1 l) with
1: Box2 (3 g, 8 l)
Total: 3.01 kg, 8.1 l
Total: 5.1 kg 28.5 l

a ja na ten moment mam taką:
Backpack (0.1 kg, 0.5 l) with
1: Ball (1.0 kg, 3.0 l)
2: Torch (0.5 kg, 1.0 l)
3: Box1 (5.0 kg, 25.0 l)
Total: 6.6, 29.5

Backpack (0.1 kg, 0.5 l) with
1: Ball (1.0 kg, 3.0 l)
2: Box1 (5.0 kg, 25.0 l)
Total: 6.1, 28.5

6.1

Backpack (0.1 kg, 0.5 l) with
1: Ball (1.0 kg, 3.0 l)
2: Box1 (5.0 kg, 25.0 l)
3: Backpack (0.01 kg, 0.1 l)
Total: 6.109999999999999, 28.6

Backpack (0.01 kg, 0.1 l) with
1: Box2 (3.0 kg, 8.000000000000002 l)
2: Box3 (1.0 kg, 4.000000000000001 l)
Total: 4.01, 12.100000000000003

GE
  • Rejestracja:ponad 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:29
0

Dodałem konstruktor w klasie Thing:

Kopiuj
   public Thing((Safe small) {
        this.small = small;
    }

i metodę w klasie Safe

Kopiuj
void add(Safe small) {

              element.item.add(new Thing(small));
    }

ale zwraca mi zera. Dalej o czymś nie wiem...

edytowany 2x, ostatnio: geoinfomat

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.