Dostęp i korzystanie z obiektów innych klas

Dostęp i korzystanie z obiektów innych klas
SlowSheep
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Kraków
  • Postów:19
0

Cześc,

Chciałbym dobrze zrozumieć procesy związane z dostępem do obiektów innych klas. Temat wydaje się prosty, ale zawsze mam wrażenie, że czegoś nie wiem.
Spójrzmy na przykład poniżej. Mam klasę Green i klasę Blue, która dziedziczy po klasie Green. W metodzie "metoda1" mam po jednym zainicjalizowanym obiekcie obu klas. Zadeklarowana jest także metoda getGreen() zwracająca obiekt green. To co chcę tutaj zrobić to uzyskać dostęp do obiektu green przez klasę Blue. Kod poniżej ma wypisać dwie linijki z adresem obiektu green, bezpośrednio z klady Green a następnie z klasy Blue poprzez wywołanie metody getGreen(). Mógłby mi ktoś wytłumaczyć dlaczego po kompilacji druga linijka zwraca null? Co powoduje, że getGreen() wywołana w klasie Blue zwraca jedynie pustą zmienną green?
Czy jest możliwe korzystanie z obiektu green przez klasę Blue bez przesyłania go jako argumentu do metody w klasie Blue? Byłbym również bardzo wdzięczny za polecenie dobrych materiałów, które dobrze opisują tego typu problemy.

Kopiuj
public class Green   {

	private Green green;
	private Blue blue;	
	
public void metoda1() {
	
	green = new Green();
	blue = new Blue();
	
	System.out.println(getGreen());
	
	blue.metoda2();
}

public Green getGreen() {
	return green;
}


public static void main(String[] args) {
	
 Green obj = new Green();
 obj.metoda1();
	
}}
Kopiuj
public class Blue extends Green {
		
	public void metoda2() {
	
		System.out.println(getGreen());
		
	}
}
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Obydwie instancje Twoich klas są niezależne od siebie - mają niezależny zestaw pól, niezależnie od tego czy dziedziczą po sobie, czy też nie.

Podobny przypadek, na którym być może lepiej będzie zobrazowana sytuacja:

Kopiuj
abstract class Entity {
  private int health;

  void setHealth(int value) {
    this.health = value;
  }

  int getHealth() {
    return this.health;
  }
}

class Hero extends Entity {
}

class Monster extends Entity {
}

/* ... */

pubilc static void main() {
  Hero = new Hero();
  Monster = new Monster();

  hero.setHealth(10);
  monster.setHealth(20);

  hero.getHealth(); // zwróci 10
  monster.getHealth(); // zwróci 20
}

Mimo że zarówno Hero jak i Monster dziedziczą po Entity, w którym znajduje się pole health, obydwie instancje mają niezależny zestaw pól - modyfikacja jednego obiektu nie wpływa na drugi.

To samo dzieje się u Ciebie - zamień tylko health na green.


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

Cała ta hierarchia nie ma sensu, ale zalecam zrobić te pola klasy final i inicjalizować konstruktorem i wtedy IDE samo ci zasugeruje że brakuje ci inicjalizacji pól odziedziczonych.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
SlowSheep
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Kraków
  • Postów:19
0
Patryk27 napisał(a):

Mimo że zarówno Hero jak i Monster dziedziczą po Entity, w którym znajduje się pole health, obydwie instancje mają niezależny zestaw pól - modyfikacja jednego obiektu nie wpływa na drugi.

To samo dzieje się u Ciebie - zamień tylko health na green.

Dzięki za odpowiedzi, chodzi mi jednak o coś trochę innego. Nawiązując do klas Monster i Hero czy jest możliwe aby klasa Monster mogła użyć obiektu Hero w taki sam sposób jak klasa Hero czyli hero.setHealth(10); ?

W moim przykładzie klasa Blue próbuje użyć obiektu Green poprzez użycie gettera GetGreen(). Zwracany jest jednak null, który prowadzi później do NullPointerException. I nie rozumiem za bardzo dlaczego metoda zwraca pustą zmienną green. Jeśli natomiast w getterze getGreen() umieszczę inicjalizację green = new Green(); to owszem to działa i klasa Blue korzysta z tego obiektu, ale zainicjalizowany tutaj obiekt green wskazuje na inny adres niż obiekt green zainicjalizowany wcześniej w metodzie Green. Czy jest możliwe aby getGreen() zwracał do metody Blue ten ten sam obiekt green utworzony w metodzie Green?
Przepraszam jeśli zbyt haotycznie to opisałem. =)

SN
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:11
1
SlowSheep napisał(a):

W moim przykładzie klasa Blue próbuje użyć obiektu Green poprzez użycie gettera GetGreen(). Zwracany jest jednak null, który prowadzi później do NullPointerException. I nie rozumiem za bardzo dlaczego metoda zwraca pustą zmienną green.

Dla mnie na przykład zaskakujące jest, że spodziewasz się, że ten wyjątek nie poleci ;-) Więc może będzie łatwiej wskazać gdzie się mylisz w swoim rozumowaniu, jeśli to rozumowanie wytłumaczysz.
Więc jak Ty to widzisz - dlaczego według Ciebie getGreen() który wywołujesz w Blue.metoda2() powinien zwrócić coś innego, niż null? Skąd Twoim zdaniem miałoby się wziąć coś w polu green w obiekcie blue?

Delor
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
1
Kopiuj
public void metoda1() {  //1

    green = new Green(); //2
    blue = new Blue(); //3

    System.out.println(getGreen());

    blue.metoda2();  //4
}

blue z 3 (czyli obj.blue) ma własne pole green (obj.blue.green) inne niż to z 2 (obj.green). 4 zwraca null bo obj.blue.green jest inicjowane dopiero w obj.blue.metoda1().

Jeżeli chcesz w 4 zwrócić green z 2 to przypisz go wcześniej np: blue.setGreen(green);.

SlowSheep
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Kraków
  • Postów:19
0
Delor napisał(a):
Kopiuj
public void metoda1() {  //1

    green = new Green(); //2
    blue = new Blue(); //3

    System.out.println(getGreen());

    blue.metoda2();  //4
}

blue z 3 (czyli obj.blue) ma własne pole green (obj.blue.green) inne niż to z 2 (obj.green). 4 zwraca null bo obj.blue.green jest inicjowane dopiero w obj.blue.metoda1().

Jeżeli chcesz w 4 zwrócić green z 2 to przypisz go wcześniej np: blue.setGreen(green);.

Dzięki za to wytłumaczenie, z jakiegoś względu kompletnie umknęło mi to, że cały czas działam tak naprawdę w obszarze obiektu o nazwie obj.

Skok Napięcia napisał(a):
SlowSheep napisał(a):

W moim przykładzie klasa Blue próbuje użyć obiektu Green poprzez użycie gettera GetGreen(). Zwracany jest jednak null, który prowadzi później do NullPointerException. I nie rozumiem za bardzo dlaczego metoda zwraca pustą zmienną green.

Dla mnie na przykład zaskakujące jest, że spodziewasz się, że ten wyjątek nie poleci ;-) Więc może będzie łatwiej wskazać gdzie się mylisz w swoim rozumowaniu, jeśli to rozumowanie wytłumaczysz.
Więc jak Ty to widzisz - dlaczego według Ciebie getGreen() który wywołujesz w Blue.metoda2() powinien zwrócić coś innego, niż null? Skąd Twoim zdaniem miałoby się wziąć coś w polu green w obiekcie blue?

Błąd w moim rozumowaniu tkwił chyba w tym, że uważałem zadeklarowaną zmienną green na samej górze jako coś w rodzaju zmiennej statycznej. Zakładałem również, że jeśli getGreen() w metoda1() zwraca adres obiektu green to tak samo powinno być gdy metodę getGreen() wywołuję z klasy Blue. Ale przyznam, że dobre pytanie mi zadałeś, powinienem sobie je częściej zadawać próbując coś rozwikłać.

Prosiłbym jeszcze o potwierdzenie czy teraz dobrze to rozumuję. W metodzie main mam zainicjalizowany obiekt o nazwie obj. Wywołuje on metodę metoda1() i zmienna green będzie obiektem tylko dla obiektu obj. Dlatego jeśli chcę się odnieść z zewnątrz do zmiennej green jako obiektu to mogę to zrobić poprzez obj.green. Inne sposoby będą zwracały null, ponieważ zmienna green nie będzie już obiektem poza obszarem obj (chyba, że skorzystam z metody setGreen(green), która mi ustawi tę zmienną dla konkretnego obiektu np. blue.setGreen(green)).

Delor
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
1
SlowSheep napisał(a):

Prosiłbym jeszcze o potwierdzenie czy teraz dobrze to rozumuję. W metodzie main mam zainicjalizowany obiekt o nazwie obj.

Zgadza się. Na początek z niezainicjowanymi zmiennymi green i blue (wskazującymi na null).

Wywołuje on metodę metoda1() i zmienna green będzie obiektem tylko dla obiektu obj.

I zmienna green będzie wskazywać na obiekt. Obiekt będzie istniał.

Dlatego jeśli chcę się odnieść z zewnątrz do zmiennej green jako obiektu to mogę to zrobić poprzez obj.green.

Skądkolwiek. Nie tylko z zewnątrz ale z obok i z wewnątrz. (Inna sprawa to w jaki sposób inni się o nim dowiedzą).

Inne sposoby będą zwracały null, ponieważ zmienna green nie będzie już obiektem poza obszarem obj ...

Będzie (wskazywać na obiekt). Ale to jest inna zmienna niż obj.blue.green i inna niż obj.green.green.

obj, obj.green i obj.blue są tak naprawdę zmiennymi które wskazują na różne obiekty klasy Green. Każda z nich jest inicjalizowana w innym miejscu. Każdy obiekt, na który wskazują, zawiera kolejne zmienne i te zmienne też trzeba inicjalizować.

SlowSheep
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Kraków
  • Postów:19
0

Dzięki za objaśnienie Delor. Teraz już wszystko mi się poukładało.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)