JAVA- wykład 2
Treści prezentowane w wykładzie zostały oparte o:
● Barteczko, JAVA Programowanie praktyczne od podstaw, PWN, 2014
● C. S. Horstmann, G. Cornell, Java. Podstawy, Helion, Gliwice 2008
● A. Zoła, Programowanie w języku Java, 2004 http://fatcat.ftj.agh.edu.pl/~palka/public/java_pl.pdf
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 2
1. Klasy i obiekty w JavieDefiniowanie klasy jest równoznaczne z tworzeniem wzorca (przepisu) danego obiektu, który umożliwia tworzenie obiektów tej klasy.
[atrybutyDostepu] class NazwaKlasy [extends NazwaNadklasy] [implements NazwyInterfejsów]
{//ciało klasy tj.
//definicje składowych klasy:
//pól, konstruktorów, metod, bloków inicjujących
}
Wyróżnia się cztery atrybuty dostępu:
● public (publiczny)-możliwość dostępu z dowolnej klasy
● protected (chroniony)-możliwość dostępu z każdej klasy pochodnej lub klas należących do tego samego pakietu
● private (prywatny)-możliwość dostępu wyłącznie w danej klasie
● dostęp domyślny (bez podanego specyfikatora dostępu)- możliwość dostępu wyłącznie z klas należących do tego samego pakietu
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 3
POLA● UWAGA: w pliku źródłowym może występować tylko jedna klasa
publiczna i jeśli występuje, to plik musi mieć taką samą nazwę jak ta klasa, z uwzględnieniem wielkości liter.
● W ciele klasy definiowane są składniki klasy, tj. zmienne (pola) i metody. Pola określają z jakich elementów składają się poszczególne obiekty klasy, zaś metody określają działania, które można na nich wykonywać.
● DEFINIOWANIE PÓL KLASY
[specyfikator_dostępu][static] nazwa_typu nazwa_zmiennej [inicjator];
● Przykład
public class Para {
private int a;
private int b; // = 6;
//...
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 4
METODY
● Przy tworzeniu obiektów pola klasy zawsze uzyskują początkowe, domyślne wartości (zerowe)
● DEFINIOWANIE METOD KLASY
[public ]class NazwaKlasy{
//...
[specyfikator_dostępu][static] typ_wyniku
nazwa_metody(lista parametrów){
//ciało metody tj.
//instrukcje wykonywane po wywołaniu metody
}
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 5
METODY
● Lista parametrów zawiera rozdzielone przecinkami deklaracje parametrów, które metoda otrzymuje przy wywołaniu.
● Jeśli metoda zwraca wynik, to w definicji określamy konkretny typ_wyniku i zakończenie jej działania powinno nastąpić na skutek instrukcji return [wyrażenie];zwracającej dane typu_wyniku, jeśli nie zwraca żadnego wyniku, to jej typ_wyniku określamy słowem kluczowym void (zakończenie metody następuje po dotarciu do ostatniego nawiasu „}” lub” instrukcji return;).
● W Javie argumenty przekazywane są metodom wyłącznie przez wartość, tj. w metodzie odwołujemy się do kopii argumentu.
● Metody statyczne (static) nie są wywoływane na rzecz obiektów, mogą zatem być wywoływane nawet, gdy nie istnieje żaden obiekt danej klasy.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 6
KONSTRUKTORY● Konstruktor służy głównie do inicjowania wartości pól obiektów.
Konstruktor ma nazwę jak nazwa klasy i nie ma żadnego typu wyniku.
● DEFINIOWANIE KONSTRUKTORÓW
[public ]class NazwaKlasy{
[specyfikator_dostępu]
nazwa_klasy(lista_parametrów){
//czynności wykonywane przez konstruktor
}
}
● Konstruktory zawsze są wywoływane za pomocą wyrażenia new : NazwaKlasy tworzonyObiekt = new NazwaKlasy(parametryKonstruktora)
● Jeśli w klasie nie zdefiniowano żadnego konstruktora, to do definicji klasy automatycznie dodawany jest konstruktor bezparametrowy (który nie robi nic).
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 7
KONSTRUKTORY c.d.
● PRZYKŁAD
public class Para{
private int a, b;
public Para(int x, int y){
a=x;b=y;//nadaje polom a i b, wartości
//przekazane jako argumenty konstruktora
}
public Para(int x){
a=x; b=x;//nadaje obu polom wartość x
}
}
Dla tak zdefiniowanej klasy, możemy tworzyć obiekty:
Para p1 = new Para(10,7); // para 10 7
Para p2 = new Para(5); //para 5 5
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 8
SKŁADOWE STATYCZNE
● Składowe (pola i metody) niestatyczne (instancyjne) zawsze wiążą się z istnieniem obiektu danej klasy
● Składowe statyczne (klasowe) tzn. ze specyfikatorem static
nie dotyczą obiektów, ale całej klasy – są wspólne dla wszystkich obiektów tej klasy
mogą być używane nawet wtedy, gdy nie istnieje żaden obiekt klasy
do składowych statycznych odwołujemy się NazwaKlasy.nazwaSkładowej
PRZYKŁADY
● metoda main – musi być statyczna ponieważ od niej zaczyna się wykonywanie programu, a w tym momencie nie istnieje jeszcze żaden obiekt.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 9
SKŁADOWE STATYCZNE c.d.
● W klasie System (dostarczanej jako klasa standardowa) jest stała statyczna out (obiekt klasy PrintStream oznaczający standardowe wyjście)
public class System{
. . .
public final static PrintStream out;
. . .
}
W klasie PrintStream (jedna z klas standardowych) zdefiniowane są metody println, wypisujące do strumienia wyjściowego -PrintStream podane argumenty
public class PrintStream{
. . .
public void println(String s){...}
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 10
SKŁADOWE STATYCZNE c.d.
Zatem
● System.out to statyczne pole klasy System
● println to metoda używana na rzecz tego obiektu
Stąd: System.out.println(String s)
UWAGI:
● Pola niestatyczne (instancyjne) istnieją w każdym obiekcie klasy, natomiast dla pól statycznych (klasowych) przydzielany jest tylko jeden obszar pamięci na całą klasę
● Z metod statycznych nie wolno odwoływać się do niestatycznych składowych klasy (gdyż obiekt może nie istnieć)
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 11
PRZECIĄŻANIE METOD● Przeciążanie metod i konstruktorów polega na definiowaniu metod o
tej samej nazwie, ale różniących się liczbą i/lub typami argumentów np. metoda println() ma bardzo wiele wersji z argumentami różnych typów.
● PRZYKŁAD dla klasy Para o prywatnych polach int a,b
void add(Para p)//dodaje do pary, na rzecz
//której wywołano metodę, parę p
void add(int i)//do obu pól pary dodaje podaną liczbę
void add(int x, int y)//pierwszy argument dodaje do
//1-go skł. Pary, a 2-gi do 2-go
● UWAGA: Należy specyfikować parametry o radykalnie różnych typach (aby uniknąć pomyłek wynikających z automatycznej konwersji typów) np. dla dwóch metod o tej samej nazwie z parametrami int i short, próba wywołania metody z parametrem char spowoduje wywołanie metody z parametrem int
● Nie istnieje możliwość deklarowania metod o tej samej nazwie, sygnaturze, ale o rożnym typie wyniku.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 12
PRZECIĄŻANIE KONSTRUKTORÓW
● Analogicznie możemy przeciążać konstruktory, czyli w jednej klasie możemy mieć konstruktory z różnymi parametrami. Aby nie powtarzać wspólnego kodu w różnych konstruktorach wygodnie jest wywoływać konstruktor w innym konstruktorze. Do takich wywołań używamy słowa kluczowego this().
● PRZYKŁAD
public class Para{
private int a,b;
public Para(){}//konstruktor bezparametrowy
public Para(int x, int y){a=x; b=y;}
public Para(int x){
this(x,x);
}
}//this(...) musi być 1 instrukcją w ciele konstruktora
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 13
OBIEKTY I REFERENCJE
public class Para{
private int a,b;
public Para(){}//konstruktor bezparametrowy
public Para(int x, int y){
a=x;b=y;
}
//metoda ustalająca składniki pary
public void set(int x, int y){
a=x;b=y;
}
//metoda pokazująca parę
public void show(){
System.out.println(”(”+a+”,”+b+”)”);
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 14
OBIEKTY I REFERENCJE
● Fragment funkcji main() z klasy TestPary:
Para p=new Para();//wywołanie konstruktora bezparametrowego
p.set(1,2);
p.show();
● Obiekt musi być utworzony za pomocą wyrażenia new (Sama deklaracja np. Para p; nie wystarcza). Dopiero zastosowanie wyrażenia new powoduje przydzielenie pamięci dla obiektu (na stercie). Wynikiem tego wyrażenia jest adres miejsca w pamięci przydzielonego obiektowi – referencja. Zatem zmienna p z przykładu zawiera referencję do obiektu klasy Para.
● Wszystkie zmienne deklarowane z nazwą klasy w miejscu nazwy typu są zmiennymi typu referencyjnego (zawierają referencje do obiektów lub null).
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 15
OBIEKTY I REFERENCJE
● Dla zmiennych typów referencyjnych możemy:
– Porównywać referencję ( == lub !=)
– Przypisywać im wartości innych referencji oraz null
● Operacje wykonywane na zmiennych obiektowych dotyczą referencji, a nie obiektów (operacje arytmetyczne są niedozwolone). Na obiektach (ich wnętrzu) operujemy za pomocą metod zdefiniowanych w klasie obiektu.
● PRZYKŁAD
Para p=new Para(1,2);//tworzony jest obiekt,wywoływany
//jest dla niego konstruktor,nadający wartości polom,
//new zwraca referencję do obiektu i podstawia pod p
Para p1=new Para();//nowy obiekt o wartościach 0,0
p1=p;//kopiujemy referencję, teraz oba obiekty
//wskazują na to samo miejsce w pamięci
p1.show(); //(1,2)
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 16
SŁOWO KLUCZOWE this● Wyrażenie new tworzy obiekt (przydziela pamięć i inicjuje wartości
zerami), a następnie dla nowo utworzonego obiektu uruchamiany jest konstruktor. W konstruktorze dostępna jest referencja do tego obiektu w postaci niejawnie zdefiniowanej zmiennej this.
public Para(int a, int b){
this.a=a; this.b=b;
}
//this.a, this.b pola obiektu inicjowanego
//przez konstruktor
//lub na rzecz którego wywołano metodę
● Obiekt na rzecz którego wywołano metodę, jest wewnątrz metody reprezentowany słowem kluczowym this.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 17
SŁOWO KLUCZOWE this● Metoda zwracająca referencję do obiektu na rzecz którego
została wywołana, np. metoda dodająca parę przekazaną jako argument do pary, na rzecz której wywołano metodę
Para add(Para p){
a+=p.a; b+=p.b;
return this;
}
Przykładowe wykorzystanie powyższej metody:
Para suma=new Para(0,0);
Para p1=new Para(1,2);
Para p2=new Para(3,4);
suma.add(p1).add(p2);
● this(...) użyte jako pierwsza instrukcja konstruktora pozwala wywołać w nim inny konstruktor
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 18
ZASIĘG ZMIENNYCH
● W każdej metodzie/konstruktorze klasy możemy odwołać się do identyfikatorów składowych klasy(pól i metod) niezależnie od tego w którym miejscu klasy są zadeklarowane.
● Zmienne zadeklarowane w metodzie/konstruktorze czyli tzw. zmienne lokalne mają zasięg lokalny- od miejsca deklaracji do końca metody, dotyczy to również parametrów deklarowanych w nagłówku metody. Zmienne lokalne muszą mieć nadane wartości (w przeciwnym przypadku -błąd kompilacji).
● Zmienne deklarowane wewnątrz bloków lokalnych (zestaw instrukcji ujęty w {}) mają zasięg od miejsca deklaracji do końca bloku. Wartości zmiennych lokalnych są tracone po wyjściu sterowania z bloku (automatyczne zwolnienie pamięci).
● Java sama dba o to, aby usunąć obiekt, gdy nie istnieje już żaden wskaźnik do niego. Zajmuje się tym tak zwany garbage collector. Jeżeli w klasie zostanie zadeklarowana metoda finalize(), to będzie ona wywoływana przed zwolnieniem pamięci przydzielonej każdemu obiektowi tej klasy.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 19
PAKIETY
● Pakiety(ang.packages) są zbiorami(bibliotekami) klas służącymi ich logicznej organizacji. Pakiet grupuje klasy o wspólnej funkcjonalności.
● Standardowa biblioteka Javy składa się z wielu pakietów, do których należą java.lang, java.util, java.net. Mają one strukturę hierarchiczną. Pakiety mogą zawierać klasy, a także inne pakiety, podobnie jak w przypadku katalogów i podkatalogów. Wszystkie standardowe pakiety Javy znajdują się w pakietach java i javax.
● Pakiety chronią nas przed kolizjami nazw. Może istnieć wiele klas o takich samych nazwach w różnych pakietach np. File, dlatego używamy nazw kwalifikowanych: nazwa_pakietu.nazwa_klasy np.java.io.File f= new java.io.File(”plik.txt”);
● Każda klasa należy do jakiegoś pakietu. Dla klas definiowanych w naszych przykładach używany był pakiet domyślny (zwykle bieżący katalog).
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 20
PAKIETY c.d.● Aby zachować unikalność nazw pakietów zaleca się stosowanie
w tych nazwach odwróconych domen internetowych(które są unikatowe)
● Klasy są przechowywane w podkatalogach systemu plików. Ścieżka do klasy musi odpowiadać nazwie jej pakietu. Nazwy pakietów zwyczajowo pisze się małymi literami. Kolejne poziomy zagnieżdżenia w hierarchii pakietów oddziela się od siebie kropkami, podobnie do tego jak nazwy kolejnych katalogów w ścieżce dostępu oddziela się od siebie ukośnikami.
● Jeśli zatem deklarujemy, że klasa należy do pewnego pakietu, to plik zawierający implementację tej klasy musi znajdować się w katalogu odpowiadającym temu pakietowi.
● Przykładowo, jeśli plik zawierający definicję klasy HelloWorld znajduje się w katalogu pl/naukajavy, to klasa ta należy do pakietu pl.naukajavy.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 21
PAKIETY c.d.● Pakiety klas są zwykle przechowywane w plikach JAR (Java
ARchive) lub ZIP. Pliki Jar zawierają skompresowane pliki klas i katalogi.
● Klasy zdefiniowane w nienazwanym pakiecie (tj. bez użycia dyrektywy package) mają nazwy proste np. Para.
● Przy tworzeniu większych projektów lub klas, używanych w innych programach, klasy umieszczamy w nazwanych pakietach, stosując dyrektywę package. (W NetBeans wystarczy podać nazwę pakietu w dialogu definiowania klasy, a automatycznie wygenerowany plik źródłowy będzie zawierał odpowiednią dyrektywę package) np. :
package pl.naukajavy;public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 22
IMPORTOWANIE KLAS
● Deklaracja importu pozwala na używanie nazw uproszczonych
import nazwa_pakietu.*; //importuje wszystkie
//nazwy klas z pakietu nazwa_pakietu
import nazwa_pakietu.KonkretnaKlasa;
//importuje nazwę klasy
np.:
import java.io.*;
class A{
File f=new File(”plik.txt”);
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 23
IMPORTOWANIE KLAS● Klasy String i System pochodzą z pakietu java.lang. Nie
wymaga on importu, nazwy klas z tego pakietu są importowane domyślnie.
● Importowanie nazw klas nie oznacza wstawiania ich definicji do programu, umożliwia on tylko posługiwanie się nazwami skróconymi
● Import statyczny umożliwia odwołania do składowych statycznych
import static nazwa_pakietu.*;
import static nazwa_pakietu.KonkretnaKlasa;
np.: import static java.lang.System.out;
public class MojaKlasa{
public static void main(String[] args){
out.println(”krócej”);
}
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 24
STRUKTURA PROGRAMU
● Program w Javie to zestaw definicji klas
● Poza ciałem klasy nie może być żadnego kodu, poza dyrektywami package, importu i komentarzami
package … //nieobowiązkowa deklaracja pakietu
import …//deklaracje importu
public class A{…}
class B{…}
● Program może być zapisany w 1 lub wielu plikach (.java) (W pliku może być tylko 1 klasa publiczna)
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 25
DZIEDZICZENIE● Dziedziczenie polega na przejęciu właściwości i funkcjonalności
obiektów pewnej klasy, z ewentualną ich modyfikacją i/lub uzupełnieniem w taki sposób, by były bardziej wyspecjalizowane.
● Definicja klasy pochodnej:
atrybut_dostępu class B extends A{…}
● Klasa A jest bezpośrednią nadklasą, superklasą, klasą bazową klasy B
● Klasa B jest bezpośrednią podklasą, klasą pochodną klasy A
● Aby utworzyć klasę pochodną od klasy z innego pakietu, klasa bazowa musi być zadeklarowana jako public (W innym przypadku nie można się do niej odwołać spoza pakietu).
● Klasa może dziedziczyć tylko po jednej nadklasie.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 26
DZIEDZICZENIE ZMIENNYCH
● Podklasa z tego samego pakietu dziedziczy wszystko oprócz zmiennych private. Podklasa, zdefiniowana poza pakietem, w którym jest klasa bazowa, nie dziedziczy zmiennych private i zmiennych z domyślnym atrybutem dostępu.
● Tabela przedstawia jak atrybuty dostępu wpływają na dziedziczenie zmiennych, gdy podklasa jest zdefiniowana w tym samym pakiecie, co klasa bazowa i gdy podklasa jest zdefiniowana w innym pakiecie.
Pakiet 2 Pakiet 1
PodKlasa Klasa PodKlasa
Nie int a; Tak int a;
public int b; Tak public int b; Tak public int b;
protected int c;
Tak protected int c;
Tak protected int c;
Nie private int e; Nie
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 27
Dziedziczenie metod
● Zwykłe metody (tzn. wszystkie metody poza konstruktorami) są dziedziczone analogicznie jak zmienne (w zależności od atrybutów).
● Konstruktory nie są nigdy dziedziczone.
● Pola klasy bazowej (najczęściej prywatne- nie mamy do nich dostępu w podklasie) inicjujemy w konstruktorze podklasy za pomocą wywołania konstruktora klasy bazowej. Co więcej, jeśli tego nie zrobimy, to kompilator sam wywoła konstruktor bezparametrowy nadklasy. Jawne wywołanie konstruktora klasy bazowej w konstruktorze podklasy(koniecznie jako pierwsza instrukcja) dokonuje się poleceniem
super(argl,...,argn);
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 28
Dziedziczenie - przykład
● PRZYKŁAD
//definicja klasy bazowej(nadklasy)
public class Zwierze {
private String gatunek;
public Zwierze(){}//konstruktor bezparametrowy
public Zwierze(String nazwa) {
gatunek = nazwa;//new String(nazwa);
}
public void coToJest() {
System.out.println("To jest " + gatunek);
}
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 29
Dziedziczenie – przykład c.d.// definicja klasy pochodnej
public class Pies extends Zwierze {
private String imie; // Imię psa
private String rasa; // Rasa
public Pies(){}//konstruktor sam wykona super()
public Pies(String toImie) {
super("Pies"); // wywołaj konstruktor nadklasy
imie = toImie; // podane imię
rasa = "Nieznana"; // domyślna rasa
}
public Pies(String toImie, String taRasa) {
super("Pies"); // wywołaj konstruktor nadklasy
imie = tolmie; // podane imię
rasa = taRasa; // podana rasa
}
}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 30
Dziedziczenie – przykład c.d.
public class Test {
public static void main(String[] args) {
Pies nowyPies = new Pies("Fido","Chihuahua"); Pies gwiazdorPies = new Pies("Lassie"); nowyPies.coToJest(); // opis gwiazdorPies.coToJest(); // i opis gwiazdora
}
}
● Klasa Pies dziedziczy po klasie Zwierzę, więc obiekty klasy Pies mają również właściwości obiektów klasy Zwierze, a zatem możemy na ich rzecz używać metod zdefiniowanych w klasie Zwierze
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 31
DZIEDZICZENIE-referencyjna konwersja rozszerzająca
● Zauważmy, że obiekty klasy Pies są również obiektami klasy Zwierze (mają jej wszelkie właściwości). Zatem referencje do obiektów klasy Pies możemy przypisać zmiennym oznaczającym obiekty klasy Zwierze : Pies p=new Pies(...); Zwierze z=p;
● Nazywamy to referencyjną konwersją rozszerzającą (widening reference conversion). Konwersja jest rozszerzająca, bo przekształcamy typ pochodny(referencja do obiektu podklasy) do typu szerszego (referencja do obiektu nadklasy)
● Zdolność obiektów do stawania się obiektem swojej nadklasy jest użyteczna.
● PRZYKŁAD: Załóżmy, że mamy nadklasę NadKlasa, z której wyprowadziliśmy podklasy: PodKlasa1, PodKlasa2.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 32
DZIEDZICZENIE – konwersja rozszerzająca
● Załóżmy, że mamy zdefiniowaną metodę public typ metoda(NadKlasa n1, NadKlasa n2){ …. }
● Wówczas dzięki automatycznej konwersji referencyjnej możemy wywoływać ją dla różnych rodzajów par: NadKlasa nkl1 = new NadKlasa(...); NadKlasa nkl2 = new NadKlasa(...); PodKlasa1 p1 = new PodKlasa1(...); PodKlasa2 p2 = new PodKlasa2(...); typ zm; zm=metoda(nkl1,nkl2); zm=metoda(nkl1,p1); zm=metoda(p1,p2);
● Gdyby nie było obiektowych konwersji rozszerzających, to dla każdej możliwej kombinacji par musielibyśmy napisać inną wersję metody metoda().
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 33
DZIEDZICZENIE-referencyjna konwersja zwężająca
● Zauważmy, że w rozważanej powyżej metodziepublic typ metoda(NadKlasa n1, NadKlasa n2){ …. }wobec parametrów n1, n2 możemy używać metod z NadKlasy, ale nie można używać metod z klas pochodnych (nawet, gdy n1, n2 wskazują na obiekty klas pochodnych)
● Referencyjna konwersja zwężająca – polega na jawnym zastosowaniu operatora rzutowania do podklasy np..:void jakasMetoda(NadKlasa n){ typ zm=((PodKlasa1)n).metodaPodKlasy1(); …}
● W przypadku, gdyby ktoś wywołał tę metodę dla obiektu podklasy PodKlasa2, zostałby wyrzucony błąd CastClassException i wykonanie programu zostałoby przerwane
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 34
OPERATOR instanceof
● Wyrażenie ref instanceof Tma wartość true, jeśli referencja ref nie jest null i może być w fazie wykonania programu rzutowana do typu T bez zgłoszenia wyjątku CastClassException tzn. jeśli referencja ref jest typu T lub dowolnego podtypu T. Wówczas:
void jakasMetoda (NadKlasa n){ typ zm; if(n instanceof PodKlasa1) zm=((PodKlasa1)n).metodaPodKlasy1() else if (n instanceof PodKlasa2) zm=((PodKlasa2)n).metodaPodKlasy2() …}
●
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 35
METODA getClass()
● Innym sposobem stwierdzania typu jest zastosowanie metody getClass(). Metoda ta zwraca faktyczny typ obiektu w postaci referencji do obiektu klasy Class. Obiekty tej klasy oznaczają klasy Pies p=new Pies(”Burek”); Zwierze z=p; Class c=z.getClass();//zmienna c będzie oznaczać klasę Pies
● Aby dowiedzieć się nazwy klasy -metoda getName() Class c=z.getClass(); String nazwa=c.getName();
● Uwaga: Różnica pomiędzy instanceof, a getClass():jeśli PodKlasa1 miałaby klasę pochodną PodPodKlasa1: PodPodKlasa1 kl=new PodPodKlasa1(...);to kl instanceof PodKlasa1 zwróci true (bo brane są pod uwagę podtypy), natomiast kl.getClass().getName() zwróci napis ”PodPodKlasa1”
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 36
DZIEDZICZENIE -nadpisywanie metod w klasie pochodnej
Metoda coToJest() z nadklasy Zwierze public void coToJest(){
System.out.println("To jest " + gatunek);
}
nie jest zbyt przydatna w klasie Pies,bo informuje tylko o cechach dostępnych w klasie Zwierze. Dopiszmy zatem w klasie Pies:public void coToJest(){ super.coToJest();//wywołanie metody bazowej //dowiemy się,że to pies, bo pole gatunek prywatne System.out.println("To jest " + imie + " z rasy " + rasa);
}
Ta metoda ma tę samą sygnaturę co metoda o tej samej nazwie w klasie bazowej i nadpisuje się nad tamtą metodę. Metoda nadpisująca metodę z klasy bazowej nie może mieć atrybutu dostępu bardziej restrykcyjnego niż metoda z klasy bazowej.
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 37
DZIEDZICZENIE - podsumowanie
● W Javie każda klasa może bezpośrednio dziedziczyć tylko po jednej klasie, ale pośrednio może mieć wiele nadklas, co wynika z hierarchii dziedziczenia. Ta hierarchia zawsze zaczyna się na klasie Object (której definicja znajduje się w zestawie standardowych klas Javy). Zatem w Javie wszystkie klasy pochodzą pośrednio od klasy Object. Jeśli definiując klasę, nie użyjemy słowa extends (nie zażądamy jawnie dziedziczenia) to i tak nasza klasa domyślnie będzie dziedziczyć klasę Object (tak jakbyśmy napisali class A extends Object). Zatem referencję do obiektu dowolnej klasy można przypisać zmiennej typu Object.
● Object
NadKlasa
PodKlasa2
PodKlasa1
PodPodKlasa1
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 38
METODY equals() i toString()● Operator == użyty wobec obiektów porównuje referencję
● Do porównywania zawartości obiektów służy metodapublic boolean equals(Object o)przedefiniowana w większości standardowych klas (np. String),która zwraca true, gdy obiekt na rzecz którego wywołano metodę ma taką samą zawartość jak obiekt, przekazany jako argument
● Dla klasy Para sami musimy ją zdefiniować, sygnatura metody musi być zawsze jak powyżej np. public class Para{ private a, b; public boolean equals(Object obj){ if (this==obj) return true; if (obj==null) return false; if (getClass()!=obj.getClass())return false; Para other=(Para)obj;//konwersja zwężająca if(a!=other.a||b!=other.b)return false; else return true; }}
12.10.2014 Dorota Pylak - Aplikacje w Javie-cz 2 39
METODY equals() i toString()
● Do przedstawiania zawartości obiektów w postaci napisów służy metoda : public String toString()wprowadzona już w klasie Object.W naszych klasach definiujemy ją sami. Jeśli metodzie println() przekażemy jako argument referencję do obiektu, to zostanie wywołana metoda toString()
● Przykładpublic class Para{ private int a,b; //....konstruktory public String toString(){ return ”(”+a+”,”+b+”)”; } public static void main(String[] args){ Para p=new Para(1,2); System.out.println(p); }}