39
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

JAVA- wykład 2

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: JAVA- wykład 2

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

Page 2: JAVA- wykład 2

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

Page 3: JAVA- wykład 2

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;

//...

}

Page 4: JAVA- wykład 2

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

}

}

Page 5: JAVA- wykład 2

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.

Page 6: JAVA- wykład 2

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).

Page 7: JAVA- wykład 2

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

Page 8: JAVA- wykład 2

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.

Page 9: JAVA- wykład 2

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){...}

}

Page 10: JAVA- wykład 2

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ć)

Page 11: JAVA- wykład 2

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.

Page 12: JAVA- wykład 2

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

Page 13: JAVA- wykład 2

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+”)”);

}

Page 14: JAVA- wykład 2

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).

Page 15: JAVA- wykład 2

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)

Page 16: JAVA- wykład 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.

Page 17: JAVA- wykład 2

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

Page 18: JAVA- wykład 2

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.

Page 19: JAVA- wykład 2

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).

Page 20: JAVA- wykład 2

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.

Page 21: JAVA- wykład 2

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!"); }}

Page 22: JAVA- wykład 2

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”);

}

Page 23: JAVA- wykład 2

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”);

}

}

Page 24: JAVA- wykład 2

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)

Page 25: JAVA- wykład 2

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.

Page 26: JAVA- wykład 2

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

Page 27: JAVA- wykład 2

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);

Page 28: JAVA- wykład 2

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);

}

}

Page 29: JAVA- wykład 2

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

}

}

Page 30: JAVA- wykład 2

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

Page 31: JAVA- wykład 2

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.

Page 32: JAVA- wykład 2

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().

Page 33: JAVA- wykład 2

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

Page 34: JAVA- wykład 2

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() …}

Page 35: JAVA- wykład 2

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”

Page 36: JAVA- wykład 2

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.

Page 37: JAVA- wykład 2

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

Page 38: JAVA- wykład 2

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; }}

Page 39: JAVA- wykład 2

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); }}