Konstruktor a parametry

Konstruktor a parametry
MA
MA
  • Rejestracja:prawie 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:4
0

Witam wszystkim,
Zwracam się z prośbą o małą pomoc :)
Napisałam sobie część takiego kodu:

Kopiuj
public class TestSerializacji {
    public static void main(String[] args){
        Papuga mango = new Papuga(42,30,true);
        
    }
}

class Papuga{
    int wielkosc = 20;
    int wiek = 1;
    boolean spiewa = true;
    
    public Papuga(int wielkoscK, int wiekK , boolean spiewaK){
        System.out.println("Test konstruktora. Stare wartości: " + wielkosc + " " + wiek + " " + spiewa);
        wielkosc = wielkoscK;
        wiek = wiekK;
        spiewa = spiewaK;
        System.out.println("Nowe wartości: " + wielkosc + " " + wiek + " " + spiewa);
    }   
}

I moje pytanie brzmi następująco: Czy jest sposób, gdy tworzę nowy obiekt typu Papuga, to mogę przesłać tylko jeden parametr np. interesuje mnie zmiana tylko wielkosci, reszta ma pozostać domyślnie (tak jak jest w klasie Papuga). Stworzyłam taki konstruktor, że za każdym razem muszę przesłać 3 parametry - ma ktoś pomysł jak mogę to zmienić (zachowując opcję zmiany z każdej wartości)?
Dziękuję z góry za pomoc :D

edytowany 1x, ostatnio: Madzionek
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

Zrób drugi konstruktor z jednym parametrem? Albo takie bardziej generyczne rozwiazanie to Builder Pattern.

Kopiuj
class Parrot {
    private final int size;
    private final int age;
    private final boolean sings;

    public Parrot(int size, int age, boolean sings) {
        this.size = size;
        this.age = age;
        this.sings = sings;
    }

    public static Builder builder() {
        return new Builder();
    }

    static class Builder {
        private int size = 20;
        private int age = 1;
        private boolean sings = true;

        public Builder withSize(int size) {
            this.size = size;
            return this;
        }

        public Builder withAge(int age) {
            this.age = age;
            return this;
        }

        public Builder withSings(boolean sings) {
            this.sings = sings;
            return this;
        }

        public Parrot build() {
            return new Parrot(size, age, sings);
        }
    }
}

public class TestPapugi {
    public static void main(String[] args) {
        Parrot parrot = Parrot.builder()
                .withAge(10)
                .build();
    }
}

Zalety buildera widać kiedy parametrów masz dużo i mogą występować w dowolnej konfiguracji. Np. chcesz móc zrobić papugę z dowolnie ustalonymi parametrami, co powoduje że konstruktorów nagle musiałoby być 1+1+3+3 = 8. Jakby parametrów było 4 to rośnie wykładniczo.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
1
  1. kilka alternatywnych konstruktorów, można zrealizować 2-3 warianty wywołania (muszą się różnić typami, więc dwa integery to pewna trudność), ale chore jest oczekiwać absolutnie wszystkich
  2. wzorzec Builder to jest to, z czym trzeba się zaprzyjaźnić

Bo C to najlepszy język, każdy uczeń ci to powie
MA
1. Myślałam o przeciążeniu, ale właśnie nie mogę, bo mam 2 takie same typy 2. Dziękuję za sugestię. Właśnie czytam co to jest i tak - to jest to czego szukałam.
MA
MA
  • Rejestracja:prawie 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:4
0

Tak! To jest właśnie to jest to, czego szukałam. Dodatkowo, teraz wiem o istnieniu Buildera.
Dziękuję za pomoc :)

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Dwa dodatkowe rozwiązania:

  1. konstruktor teleskopowy
Kopiuj
public Papuga(int wielkoscK){
  this(wielkoscK, 0, false);
}
  1. konstruktor domyślny plus setter funkcyjny a'la Yegor Bugayenko:
Kopiuj
public Papuga(){
// ... wypełnij wartościami domyślnymi
}

public Papuga withWielkosc(int wielkoscK){
   return new Papuga(wielkoscK, this.wiek, this.spiewa);
}
Zobacz pozostałe 7 komentarzy
Charles_Ray
Ok, ale dlaczego to jest problem dla GC?
AK
W tej konwencji literackiej się wypowiedział @Shalom kilka wierszy wcześniej :)
Charles_Ray
Nie podał uzasadnienia :) pytam Ciebie, bo napisałeś, że "GC płacze" - dlaczego tak uważasz? Może ja czegoś nie wiem
Shalom
Ja sobie tu śmieszkuje a wy snujecie jakieś spiskowe teorie :D W zależności od GC będzie albo nie będzie to miało wielkiego znaczenia. Dużo obiektów do zwalniania to zawsze więcej pracy dla GC, ale jak to są obiekty young to nie ma co sie spinać. Gorzej jak sobie tak wymierzysz, że robisz te kopie jak obiekt juz poleciał gdzieś do old.
Charles_Ray
Czyli rozumiem, że @AnyKtokolwiek bezmyślnie kopiuje komentarze @Shalom ?
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
2

Przejdz na Kotlina ;)


λλλ
99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
0

Skoro mamy festiwal pomysłów to i ja dodam swój, jeżeli OP czuje się komfortowo z użyciem nieco bardziej zaawansowanych zabawek to polecam Lomboka (https://projectlombok.org/features/Builder).
W tym wypadku OP napisze jedynie:

Kopiuj
@Getter
@Builder
public class Papuga {
    private final int wielkosc = 20;
    private final int wiek = 1;
    private final boolean spiewa = true;
}

a reszta wygeneruje się automatycznie (gettery i builder). Tutorial: https://www.baeldung.com/lombok-builder


Holy sh*t, with every month serenityos.org gets better & better...
Shalom
annotation driven development

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.