Ucząc się języka Java należy być świadomym, że wiedza o samych metodach nie wystarczy :O. Trzeba sobie wytłumaczyć czym jest konstruktor klasy w języku Java. Co to jest? Co on robi? Jak go zdefiniować i dlaczego jest tak ważny dla programistów? Na tym się dzisiaj skupimy.
Tweet |
CZYM JEST KONSTRUKTOR KLASY W JĘZYKU JAVA?
Gdyby ktoś się upierał przy pytaniu "co to jest konstruktor?", odpowiedzcie że jest to metoda wywoływana w momencie tworzenia kopii danej klasy, czyli obiektu. Ważne jest również rozróżnianie jednego od drugiego. Klasa to szablon/wzorzec dla obiektu, obiekt to kopia klasy. Nie będę pisał co dokładnie dzieje się "pod maską" kompilatora, wspomnę jedynie że dochodzi do zaalokowania odpowiedniego miejsca w pamięci, a sam obiekt w Javie jeżeli staje się już bezużyteczny, "znika" bez konieczności ręcznego zwalniania pamięci w wyniku działania "odśmiecacza pamięci". "Koniec żywota" obiektu uznaje się za moment, kiedy program dojdzie do końca metody, a w niej znajduje się obiekt. Samo przypisanie wartości "null" spowoduje jedynie "oznaczenie" obiektu przeznaczonego do wyrzucenia, ale faktyczne pozbycie się instancji następuje w momencie wykonania wszystkich instrukcji w metodzie.
Zaglądając do kodu źródłowego, konstruktor klasy w języku Java rozpoznaje się poprzez dwa zapisy. Pierwszy z nich dotyczy definicji. Osadzony jest w danej klasie i wygląda on tak:
public class Example {
public Example() {
// instrukcje wykonywane przed utworzeniem obiektu
}
}
Zwróćcie uwagę, że choć istotnie to jest metoda, to konstruktor różni się jednym zasadniczym szczegółem - nie podajemy nigdy typu zwracanej wartości! Po podaniu modyfikatora dostępu, od razu nadajemy nazwę. I uwaga! Nie taką jak chcemy, tylko ma się pokrywać z nazwą klasy! Zawsze!
Drugi zapis odgrywa rolę wywołania konstruktora w celu utworzenia obiektu bazującego na tej klasie i wygląda on tak:
Example e = new Example();
Po znaku przypisania, podajemy słowo kluczowe "new", a zaraz po nim piszemy IDENTYCZNĄ nazwę klasy razem z parą nawiasów okrągłych, gdyż jest to nadal metoda w rozumieniu paradygmatu obiektowego!!! Konstruktor klasy w języku Java, jak każda inna metoda, również może posiadać parametry formalne, które przydają się do inicjowania danych składowych. Ponadto, można przeciążyć konstruktory, czyli utworzyć kilka w jednej klasie różniących się listą parametrów. Warto jeszcze wspomnieć, że można uniknąć tworzenia własnych konstruktorów. Wówczas kompilator dodaje go automatycznie, a nowo wygenerowany konstruktor jest zawsze bezparametrowy i pozbawiony instrukcji (określany jest jako "domyślny").
PRZYKŁAD KODU ŹRÓDŁOWEGO
Tęsknicie za okienkami z kodem ;)? Mam dla Was kolejne. Oto przykład programu wykorzystującego konstruktor klasy w języku Java. Posiada on dwie klasy: uruchomieniową "Main" oraz "Example" służącą za przykład:
KLASA "MAIN"
public class Main {
public static void main(String[] args) {
Example a = new Example();
Example b = new Example(15);
}
}
KLASA "EXAMPLE"
public class Example {
public Example() {
System.out.println("Wypisuję tekst na wyraźne polecenie konstruktora.");
}
public Example(int n) {
System.out.println("Kazano mi, abym wyświetlił liczbę " + n);
}
}
Konstruktor klasy w języku Java działa następująco: po natrafieniu na słówko "new", program wchodzi do klasy i zagląda do odpowiedniego egzemplarza "patrząc" na listę parametrów. Ponieważ zdefiniowano dwa konstruktory, nie ma żadnych problemów z uruchomieniem i stosowne komunikaty zostaną prawidłowo wyświetlone. Jeżeli nie jesteście w stanie tego zrozumieć i stykacie się z tym po raz pierwszy, wiem z własnego doświadczenia, że jest to impuls do tego, aby się pofatygować, skopiować to sobie i skompilować. Zachęcam :D!
KONSTRUKTOR KLASY W JĘZYKU JAVA MOŻNA PODDAĆ PRZECIĄŻENIU!
Możecie dodać wiele "wersji" konstruktora stosując przeciążanie, aczkolwiek trzeba wiedzieć jak to robić dobrze, gdyż konstruktory wyróżniają się nie tylko zastosowaniem, ale także innym doborem słów kluczowych. Przy konstruktorach sprawa wygląda nieco inaczej i w tym miejscu na scenę wchodzi kolejne słowo kluczowe "this". Umożliwia ono odwoływanie się do tej samej klasy (do samego siebie, ale nie utożsamiać tego stwierdzenia z rekurencją!).
Przeciążanie konstruktorów ma takie same zastosowanie jak przeciążanie innej metody - chcemy mieć możliwość wyboru jednej z kilku "dróg" utworzenia obiektu. Chociaż cel jest identyczny, to zapis już nieco inny.
PRZYKŁAD KODU ŹRÓDŁOWEGO
Prezentuję następny program wykorzystujący omawiany manewr. W środku niego dołączyłem przeciążony konstruktor klasy w języku Java, jak również też przypadek kiedy "this" jest potrzebne w chwili przypisywania wartości danym składowym, czyli zmiennym:
KLASA "MAIN"
public class Main {
public static void main(String[] args) {
Point a = new Point();
Point b = new Point(5, 8);
System.out.println(a);
System.out.println(b);
}
}
KLASA "POINT"
public class Point {
private final int x, y;
public Point() {
this(0, 0);
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
Klasa "Point" tworzy nowy punkt w układzie dwuwymiarowym. Posiada ona przeciążanie konstruktorów i tam macie pierwsze użycie słowa kluczowego "this". Nie dajemy nazwy "Point" jak mogliście pomyśleć na wstępie :O!!! W tym przykładzie, gdy konstruktor klasy w języku Java jest bezparametrowy, to wówczas "sięga" on do drugiego konstruktora z domyślnymi wartościami i tam jest wywołana metoda "setPosition". Idąc jej śladem, natrafiamy na drugi sposób użycia "this" i jest on konieczny w celu rozróżnienia o jakie "x" i o jakie "y" nam chodzi. Gdybyście za nazwy parametrów dorzucili na przykład "newX" i "newY", to wtedy możecie odrzucić ten przedrostek, bo wtedy kompilator będzie wiedział jak je odróżnić :D.
Tak wygląda konstruktor w języku Java oraz ich przeciążanie w przełożeniu na w miarę prosty język. To wszystko na ten temat :).