16 kwietnia 2008

SCJP – Polimorfizm

Kolejny artykuł w wielkim maratonie po SCJP – kontynuacja działań zapowiedzianych w artykule "Przygotowania do SCJP czas zacząć". Tym razem będzie o polimorfizmie.

Zacznę od szybkiego wyjaśnienia, czym właściwie jest polimorfizm a w tym celu posłużę się przykładem. Zerknijmy na poniższy kod.

class A {
void test() {
System.out.println("A");
}
}

class B extends A {
void test() {
System.out.println("B");
}
}

public class Test {
public static void main(String[] args) {
A var = new A();
var.test();

var = new B();
var.test();
}
}

Uruchomienie powyższego programu spowoduje wypisanie litery A a następnie litery B. I właśnie to jest polimorfizm. Że co (ang. say what)? Ano, że to, która metoda zostanie wykonana zależy nie od typu zmiennej tylko od typu faktycznego obiektu wskazywanego przez tą zmienną. W powyższym przykładzie dwu krotnie wywołaliśmy metodę test() na zmiennej var typu A a jednak za drugim razem wywołała się metoda zdefiniowana w klasie B. Właśnie dlatego, że za drugim razem zmienna var wskazywała na obiekt klasy B. A teraz uwaga! Polimorfizm dotyczy tylko metod i to tylko metod instancji, tj. nie statycznych. Spróbujmy dopisać słówko kluczowe static w deklaracjach metod test() w klasach A i B. Polimorfizm znika – program wypisuje dwu krotnie literę A, przestaje się bowiem liczyć typ obiektu, ważny jest typ zmiennej. I jeszcze jeden przykład. Zmodyfikujmy klasy A i B tak jak pokazano poniżej.

class A {
String id = "A";

void test() {
System.out.println(id);
}
}

class B extends A {
String id = "B";
}

Jaki będzie teraz efekt działania programu? Będzie to dwu krotnie litera A. Na koniec jeszcze jeden przykład. Zastąpmy klasy A i B następującymi.

class A {
void test() {
System.out.println(getId());
}

String getId() {
return "A";
}
}

class B extends A {
String getId() {
return "B";
}
}

Tym razem program wypisze A a potem B. Metoda getId() wykonuje się przecież dla obiektu this, a obiektem tym za drugim razem jest obiekt klasy B.

6 komentarzy:

Paweł Szulc pisze...

No ładnie, ale czy ty przypadkiem powoli ksiazki o SCJP nie chcesz napisac? ;)

Mariusz Lipiński pisze...

Głównie chcę zdać SCJP, a biorąc pod uwagę czas jaki jest/będzie mi potrzebny na przetrawienie caaaałej Książki i krótkotrwałość pamięci będę potrzebował czegoś do szybkiego powtórzenia przed testem. Ale rzeczywiście, może się potem okazać że jest sporo tekstu możliwego do sensownego zagospodarowania :)

Pozdrawiam

Anonimowy pisze...

"dwu krotnie" razem;)

Łukasz pisze...

Jaki będzie wynik oraz wypisana nazwa klasy?

public static void main(String[] args) {
Person person = new Person();
Use(person);
Teacher teacher = new Teacher();
Use(teacher);

Person teacherAsPerson = new Teacher();
Use(teacherAsPerson);
}

static void Use(Person person) {
System.out.println("Person used.");
System.out.println(person.getClass().getName());
}

static void Use(Teacher teacher) {
System.out.println("Teacher used.");
}
}

class Person {
}

class Teacher extends Person {
}

Wnioskowanie po typie zmiennej czy po rodzaju obiektu? ;)

Mariusz Lipiński pisze...

Wybacz, ale twój kod jest nieczytelny - nazwy metod zaczynamy od małej litery.

Łukasz pisze...

Przepraszam, jeszcze zostały mi te przyzwyczajenia z .neta. Tam jest trochę inna konwencja.