12 marca 2008

SCJP - Deklaracja konstruktora

Deklaracja konstruktora, czyli streszczenie sekcji "Constructor Declarations" – kontynuacja działań zapowiedzianych w artykule "Przygotowania do SCJP czas zacząć". Tym razem wybiegnę jednak zakresem wiedzy sporo poza Książkę, będę się wspomagał specyfikacją języka Java.

Zacznijmy od tego, że każda klasa ma konstruktor. Jeśli nie zdefiniowaliśmy konstruktora explicite to jest on generowany przez kompilator, jest to tak zwany konstruktor domyślny. Konstruktor ten generowany jest tylko wtedy, gdy nie zdefiniowano żadnego explicite. Domyślny konstruktor, to konstruktor bezparametrowy. Jedyne, co robi konstruktor domyślny wygenerowany przez kompilator to wywołanie konstruktora bezparametrowego klasy nadrzędnej, a więc instrukcja ‘super()’. Jeśli chcemy zmienić to zachowanie to możemy konstruktor domyślny po prostu jawnie zaimplementować. Pytanie sprawdzające – czy poprawnym jest kod:

public class NewClass {
private int x;

public NewClass(int x) {
this.x = x;
}
}

public class OtherClass extends NewClass {
}

Odpowiedź brzmi NIE. Dla klasy OtherClass nie zdefiniowano żadnego konstruktora a więc kompilator wygenerował konstruktor domyślny. Konstruktor domyślny – jak napisałem powyżej – zawiera wywołanie ‘super()’. Dla klasy NewClass zdefiniowano konstruktor jednoargumentowy, więc kompilator nie wygenerował konstruktora domyślnego, nie został też taki konstruktor zdefiniowany explicite a więc wywołanie ‘super()‘ nie jest prawidłowe.

Konstruktor może mieć dowolną listę parametrów, która jest legalna dla zwykłych metod. Konstruktor deklarujemy generalnie tak jak metodę, tyle, że nie podajemy zwracanego typu - jeśli określimy typ to jest to już metoda a nie konstruktor. Konstruktor musi się nazywać dokładnie tak jak klasa, ale uwaga, metoda także może się nazywać dokładnie tak jak klasa. Zanim więc orzekniemy, że dana deklaracja jest konstruktorem – sugerując się nazwą – zwróćmy uwagę czy zadeklarowany jest zwracany typ.

Jeśli chodzi o modyfikatory, to dozwolone są wszystkie modyfikatory widoczności, jak i brak modyfikatora widoczności, co oznacza zasięg domyślny. Konstruktory nigdy nie są dziedziczone. Znaczenie modyfikatorów widoczności, z dokładnością do dziedziczenia, jest takie jak dla metod i opisałem je w artykule "SCJP - Modyfikatory widoczności w deklaracji metod i zmiennych". Inaczej niż dla metod, dla konstruktorów nie są dozwolone żadne inne modyfikatory. Jeszcze tylko jeden komentarz co do widoczności. Zdawałoby się, że skoro konstruktory nie podlegają dziedziczeniu, to nie ma różnicy między zakresem protected i zakresem domyślnym. Poniższy przykład pokazuje, że jednak taka różnica jest. Jeśli poniższe klasy są w różnych pakietach, to kod jest poprawny dla konstruktora protected, a dla zakresu domyślnego już nie.

public class NewClass {
protected NewClass() {
}
}

public class OtherClass extends NewClass {
public OtherClass() {
super();
}
}

Brak komentarzy: