Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Dziedziczenie i zmienne statyczne
peter13135
post
Post #1





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Mój "problem" dotyczy programowania obiektowego. W moim przypadku chodzi o javę, ale myślę, że to dotyczy ogólnie programowania obiektowego.
Dajmy na to, mam klasę abstrakcyjną typu wielokąt:

  1. abstract class wielokąt{
  2. private int liczbaKątów;
  3.  
  4. public int getLiczbaKątów() {return liczbaKątów; }
  5. public int setLiczbaKątów(int lk) { liczbaKątów = lk; }
  6. }


Następnie robię sobie klasę trójkąt:
  1. class trójkąt extend wielokąt{
  2.  
  3. trójkąt()//w php będzie to __construct()
  4. {
  5. setLiczbaKątów(3);
  6. }
  7.  
  8. }
  9.  


W analogiczny sposób robię sobie klasy czworokąt, pięciokąt itd.

Następnie w kodzie mam wiele instancji tych klas (trójkątów, czworokątów itd.)
Okazuje się, że mój kod jest nieco pamięciożerny, bo liczba kątów dla klasy trójkąt zawsze będzie równa 3, a ja tworzę dla każdej instancji klasy osobną zmienną.

Niby z pomocą przychodzą zmienne statyczne, ale jeśli takową zadeklaruję w klasie wielokąt, to liczba kątów dla trójkąta i czworokąta będzie taka sama.
Muszę więc zadeklarować tą zmienną statyczna w klasach potomnych, czyli w trójkącie, czworokącie,...,n-kącie. Ale wtedy moje metody zdefiniowane w klasie wielokąt nie będą działały, bo przecież w klasie wielokąt nie ma zmiennej o nazwie liczbaKątów.
Ratunkiem jest stworzenie tych metod w klasach potomnych, a w klasie nadrzędnej zostawić tylko "abstrakcyjne nagłówki".
Jednak... nie bardzo mi to pasuje, bo każda z tych metod (setter i getter) bedzie wyglądał tak samo. Nie chcę więc powielać kodu.

jak temu zaradzić ?


--------------------
:)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Na prawdę ta jedna zmienna jest przyczyną problemów z pamięcią?
2.
  1. abstract class Wielokąt {
  2. abstract public int getLiczbaKątów();
  3. }
  4.  
  5. public class Trójkąt extends Wielokąt {
  6. public int getLiczbaKątów() {
  7. return 3;
  8. }
  9. }
  10.  
  11. public class Prostokąt extends Wielokąt {
  12. public int getLiczbaKątów() {
  13. return 4;
  14. }
  15. }
3. Uprzedzając pytanie - tak, JIT "zinlineuje" wywołanie metody getLiczbaKątów().
4. Korzystanie ze static prawie nigdy nie jest dobrym pomysłem na rozwiązanie problemów.
Go to the top of the page
+Quote Post
peter13135
post
Post #3





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Cytat
1. Na prawdę ta jedna zmienna jest przyczyną problemów z pamięcią?

Nie, ta zmienna, trójkąty i czworokąty to tylko taki przykład, aby było przejrzyściej. W rzeczywistości mam kilkanaście takich zmiennych. Jedne maja typy proste. większość to dość rozbudowane obiekty, kilka z nich to pliki graficzne ładowane z dysku. Prawdopodobnie gdybym to wszystko ładował dla każdej instancji oddzielnie, to i tak współczesnemu komputerowi to wielkich problemów nie zrobi, ale mimo to, chcę to zrobić tak jak należy.
2. No fajnie, ale w każdej z tych klas potomnych robisz metodę. Tak to i ja potrafię, ale jak pisałem - chcę tego uniknąć.

Dam nieco bardziej bardziej rozbudowany i obrazowy przykład (bez kodu).
Dajmy na to, że mamy grę, w której są różne jednostki (powiedzmy smerfy i gargamele). Mamy więc klasę Jednostka, która posiada wiele "właściwości", np. szybkość, wytrzymałość, pozycja na mapie, rodzaje broni, siła uderzenia, odporność na jakieś tam ataki i mnóstwo innych. Wszelkie "akcje" czyli na przykład ruch, albo zmniejszenie punktów wytrzymałości jednostki ma robić klasa "Jednostka", czyli ta nadrzędna.

Klasy potomne jak Smerf czy Gargamel (które dziedziczą po klasie Jednostka) mają takie same "zachowania" (np. metoda ruch() będzie zwiększała pozycję o wartość szybkość) tylko na innych danych. Np. Smerf będzie miał szybkość = 2, a Gargamel szybkość = 1.

Trochę nie widzi mi się pisanie dla każdej potomnej klasy metod typu getJakasWłaściwość() {return new JakisObiekt(1,2,3,4,5,2,4,'abc')}.

Mam rozumieć, że jeśli zrobię metodę typu

getSmerfImage() {return Image("./obrazki/obrazeksmerfa.jpg")} - to w pamięci będe miał tylko jeden załadowany obraz bez względu czy będę miał 3 czy 8 smerfów ?


Aha... i czemu static "nie rozwiązuje problemów" ?

Ten post edytował peter13135 28.03.2013, 14:31:03


--------------------
:)
Go to the top of the page
+Quote Post
Crozin
post
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Jeżeli możesz podaj proszę dokładny opis swojego przypadku, ponieważ w przykładach jakie podajesz każdy obiekt powinien mieć swoją lokalną kopię danych, bądź powinien istnieć inny obiekt zwracający prędkość/ilość kątów na podstawie przekazanego mu obiektu: (raczej gorsze rozwiązanie)
  1. public int getIlośćKątów(Wielokąt wielokąt) {
  2. if (wielokąt instanceof Prosotkąt) {
  3. return 4;
  4. } else if (wielokąt instanceof Trójkąt) {
  5. return 3;
  6. }
  7.  
  8. throw new IllegalArgumentException("...");
  9. }
Cytat
Mam rozumieć, że jeśli zrobię metodę typu

getSmerfImage() {return Image("./obrazki/obrazeksmerfa.jpg")} - to w pamięci będe miał tylko jeden załadowany obraz bez względu czy będę miał 3 czy 8 smerfów ?
Nie, będziesz miał po jednym załadowanym obrazie na obiekt (bardzo złe rozwiązanie). Ale takim czymś nie powinien zajmować się już Twój obiekt Jednostka - za dużo zadań mu przydzielasz: reprezentowanie obiektu na mapie (pozycja, ruch), obiekt domeny (Smerf/Gargamel) i do tego chciałbyś jeszcze dorzucić śmieci związane z renderowaniem grafiki? Single responsibility principle.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 14:49