Wykład 7: Pakiety i Interfejsy
Plik Źródłowy w Javie Składa się z: instrukcji pakietu (pojedyncza, opcjonalna) instrukcji importujących (wielokrotne, opcjonalne) deklaracji klasy publicznej (pojedyncza, wymagana) deklaracji klas prywatnych (wielokrotne, opcjonalne) Wystarczy więc jedna deklaracja klasy publicznej.
Pakiety w Javie Do tej pory, wszystkie klas pochodziły z tej samej przestrzeni nazw. Jak zapewnić by nazwy były unikalne? Pakiet - zbiornik na klasy: dzieli przestrzeń nazw na rozłączne zbiory kontroluje widoczność klas i składowych klas
Definicja Pakietu Instrukcja pakietu umieszczona jako pierwsza komenda pliku źródłowego: package MojPakiet; Wszystkie klasy w pliku należą do pakietu MojPakiet. Inne pliki mogą posiadać tą samą instrukcję: pakiet rozkłada się na wiele plików. Wszystkie pliki.class w pakiecie MojPakiet są zapisywane w katalogu MojPakiet.
Hierarchia Pakietów Pakiet wielo-poziomowy: package pakiet1.pakiet11.pakiet111; Pliki zachowane w katalogu: pakiet1/pakiet11/pakiet111 system Unix pakiet1\pakiet11\pakiet111 system Windows pakiet1:pakiet11:pakiet111 system Macintosh
Zmienna CLASSPATH Zmienna środowiskowa która wskazuje na początek (korzeń) hierarchii pakietów w systemie. Np. katalog bieżący i katalog C:\mojaJava.;C:\mojaJava Java poszukuje pakietów przeszukując kolejne katalogi wymienione w ścieżce CLASSPATH.
Pakiety: Przykład package MojPakiet; class Balans { String nazwa; double balans; Balans(String n, double b) { name = n; bal = b; void pokaz() { if (balans < 0) System.out.println(name + ": $" + bal);
Pakiety: Przykład class Pakiet { public static void main(string args[]) { Balans biezacy[] = new Balans[3]; biezacy[0] = new Balans("T.Bialy", 123.12); biezacy[1] = new Balans("J.Schmidt", 56.12); biezacy[2] = new Balans("A.Moraw", 34.75); for (int i = 0; i < 3; i++) biezacy[i].pokaz();
Pakiety: Przykład Należy umieścić pliki.class w katalogu pakietu: cd MojPakiet javac Pakiet.java Należy uruchomić klasę odwołując się do nazwy pakietu, z poziomu gdzie katalog MojPakiet jest widoczny: cd.. java MojPakiet.Pakiet Zakładamy że katalog bieżący jest w CLASSPATH.
Ochrona Dostępu: Klasa Klasa dostępna w całym programie: public class MojaKlasa {... Klasa dostępna tylko w ramach tego samego pakietu: class MojaKlasa {...
Ochrona Dostępu: Składowe Klasy Składowa dostępna w całym programie: public int pole; public int metoda(...){... Składowa dostępna tylko w ramach danej klasy: private int pole; private int metoda(...){...
Ochrona Dostępu: Składowe Klasy Składowa dostępna w pod-klasach danej klasy i innych klasach w bieżącym pakiecie (dostęp domyślny!): int pole; int metoda(...){... Składowa dostępna tylko w pod-klasach danej klasy (również poza bieżącym pakietem): protected int pole; protected int metoda(...){...
Ochrona Dostępu: Składowe Klasy private default protected public jedna klasa tak tak tak tak jeden pakiet nie tak tak tak pod-klasa jeden pakiet nie tak tak tak nie pod-klasa różne pakiety nie nie tak tak pod-klasa różne pakiety nie nie nie tak nie pod-klasa
public class NadKlasa { int n = 1; private int npriv = 2; protected int nprot = 3; public int npub = 4; public NadKlasa() { System.out.println("NadKlasa"); System.out.println("n = " + n); System.out.println("nPrivate = " + npriv); System.out.println("nProtected = " + nprot); System.out.println("nPublic = " + npub); Ochrona Dostępu: Przykład Nad-klasa w pakiecie p1: package p1;
Ochrona Dostępu: Przykład Pod-klasa w pakiecie p1: package p1; class PodKlasa extends NadKlasa { PodKlasa() { System.out.println("PodKlasa"); System.out.println("n = " + n); //System.out.println("nPrivate = " + npriv); System.out.println("nProtected = " + nprot); System.out.println("nPublic = " + npub);
Ochrona Dostępu: Przykład Inna klasa w pakiecie p1: package p1; class JedenPakiet { JedenPakiet() { NadKlasa k = new NadKlasa(); System.out.println("JedenPakiet"); System.out.println("n = " + k.n); //System.out.println("nPrivate =" + k.npriv); System.out.println("nProtected =" + k.nprot); System.out.println("nPublic =" + k.npub);
Ochrona Dostępu: Przykład Klasa wykonawcza w pakiecie p1: package p1; public class Pakiet1 { public static void main(string args[]) { NadKlasa k1 = new NadKlasa(); PodKlasa k2 = new PodKlasa(); JedenPakiet k3 = new JedenPakiet();
Ochrona Dostępu: Przykład Nad-klasa w pakiecie p2: package p2; class NadKlasa2 extends p1.nadklasa { NadKlasa2() { System.out.println("NadKlasa2"); //System.out.println("n = " + n); //System.out.println("nPrivate = " + npriv); System.out.println("nProtected = " + nprot); System.out.println("nPublic = " + npub);
Ochrona Dostępu: Przykład Inna klasa w pakiecie p2: package p2; class InnyPakiet { InnyPakiet() { p1.nadklasa k = new p1.nadklasa(); System.out.println("InnyPakiet"); //System.out.println("n = " + k.n); //System.out.println("nPrivate =" + k.npriv); //System.out.println("nProtected ="+k.nprot); System.out.println("nPublic = " + k.npub);
Ochrona Dostępu: Przykład Klasa wykonawcza w pakiecie p2: package p2; public class Pakiet2 { public static void main(string args[]) { NadKlasa2 k1 = new NadKlasa2(); InnyPakiet k2 = new InnyPakiet();
Importowanie Pakietów Umożliwia bezpośrednie odwołanie do klasy przez jej nazwę, bez potrzeby wymieniania wszystkich pakietów. Importowanie konkretnej klasy: import pakiet1.pakiet2.klasa; Importowanie wszystkich klas danego pakietu: import pakiet1.pakiet2.*;
Deklaracja Import Występuje zaraz po instrukcji pakietu, a przed deklaracją klasy: package pakiet; import pakiet1.pakiet2.klasa; class Klasa {... Kompilator domyślnie przyjmuje tą deklarację: import java.lang.*;
Konflikty Nazw Jeśli klasa o tej samej nazwie występuje w dwóch różnych pakietach importowanych do programu: import pakiet1.*; import pakiet2.*; kompilator wyświetli komunikat błędu gdy spróbujemy użyć jednej z klas. Należy wówczas użyć pełnej nazwy: pakiet1.klasa pakiet2.klasa
Odwołania Skrócone i Pełne Odwołanie skrócone: import java.util.*; class MojaKlasa extends Date {... Odwołanie pełne: class MojaKlasa extends java.util.date {... Tylko składowe public w importowanym pakiecie, są dostępne dla nie-pod-klas w importującym kodzie.
Importowanie Klas: Przykład package MojPakiet; public class Balans { String nazwa; double balans; public Balans(String n, double b) { nazwa = n; balans = b; public void pokaz() { if (balans < 0) System.out.println(nazwa + ":$" + balans);
Importowanie Klas: Przykład import MojPakiet.*; class Importowanie { public static void main(string args[]) { Balans test = new Balans("T.Bialy",-12.57); test.pokaz();
Interfejs Interfejs jest podobny do klasy która posiada tylko metody pozbawione implementacji. wiele klas może implementować jeden interfejs jedna klasa może implementować wiele interfejsów Klasa implementuje dany interfejs jeśli dostarcza definicji dla wszystkich jego metod.
Definicja Interfejsu dostęp interface nazwa { typ metoda1(lista-parametrów);... typ metodan(lista-parametrów); typ zmienna1 = wartość;... typ zmiennam = wartość; Dwa rodzaje dostępu: public może być użyty gdziekolwiek w programie domyślny dostępny tylko w bieżącym pakiecie Zmiennie są static, final, inicjowane stałą.
Implementacja Interfejsu Ogólna postać definicji klasy: dostęp class nazwa extends nad-klasa implements interfejs1,..., interfejsn {... Dostęp public lub domyślny. Metody implementujące interfejs muszą być public, oraz posiadać dokładnie ten sam typ jak w interfejsie.
Interfejs: Przykład Deklaracja interfejsu: interface MojInterfejs { void metoda(int par); Klasa implementująca interfejs: class Klasa implements MojInterfejs { public void metoda(int p) { System.out.println("parametr: " + p);
Interfejs: Przykład Klasa implementująca może deklarować własne metody: class Klasa implements MojInterfejs { public void metoda(int p) { System.out.println("parametr: " + p); void innametoda() { System.out.println("Inna metoda");
Interfejs i Zmienne Obiektowe Deklaracja zmiennej której typem jest interfejs. MojInterfejs mi; Wartością zmiennej może być odwołanie do obiektu dowolnej klasy która implementuje ten interfejs. MojInterfejs mi = new Klasa(); class Klasa implements MojInterfejs {...
Wywołanie Metody przez Zmienną Przez zmienną której typem jest interfejs można wywołać dowolną metodę w tym interfejsie: mi.metoda(42); Nie można wywołać metody która nie jest w interfejsie: mi.innametoda(); Wywoła się poprawna wersja metody, odpowiednio dla faktycznego obiektu wskazywanego przez zmienną.
Polimorfizm przez Interfejs interface MojInterfejs { void metoda(int par); class Klasa1 implements MojInterfejs { public void metoda(int p) { System.out.println("parametr: " + p); class Klasa2 implements MojInterfejs { public void metoda(int p) { System.out.println("kwadrat: " + (p*p));
Polimorfizm przez Interfejs class PolimorfizmInterfejs { public static void main(string args[]) { MojInterfejs mi; Klasa1 k1 = new Klasa1(); Klasa2 k2 = new Klasa2(); mi = k1; mi.metoda(42); mi = k2; mi.metoda(6);
Interfejs i Klasa Abstrakcyjna Klasa która zawiera interfejs, ale nie implementuje wszystkich jego metod, musi być abstrakcyjna. abstract class KlasaCzesciowa implements MojInterfejs { int a,b; void pokaz() { System.out.println(a + " " + b);
Zmienne w Interfejsie Importowanie stałych do wielu klas przez interfejs który posiada tylko zmienne. import java.util.random; interface Stale { int NIE = 0; int TAK = 1; int MOZE = 2;
Zmienne w Interfejsie: Przykład class Pytanie implements Stale { Random rand = new Random(); int pytanie() { int test = (int)(100* rand.nextdouble()); if (test < 30) return NIE; else if (test < 75) return MOZE; else return TAK;
Zmienne w Interfejsie: Przykład class ZapytajMnie implements Stale { static void odpowiedz(int wynik) { switch(wynik) { case NIE:System.out.print("Nie");break; case TAK:System.out.print("Tak");break; case MOZE:System.out.print("Moze");break; public static void main(string args[]) { Pytanie p = new Pytanie(); odpowiedz(p.pytanie()); odpowiedz(p.pytanie()); odpowiedz(p.pytanie());
Dziedziczenie Interfejsów Jeden interfejs może dziedziczyć po innym: interface A { void metoda1(); void metoda2(); interface B extends A { void metoda3(); Klasa implementująca musi dostarczyć definicji dla wszystkich metod w kolejnych interfejsach.
Dziedziczenie: Przykład class MojaKlasa implements B { public void metoda1() { System.out.println("metoda1"); public void metoda2() { System.out.println("metoda2"); public void metoda3() { System.out.println("metoda3");
Dziedziczenie: Przykład class InterfejsDziedziczenie { public static void main(string args[]) { MojaKlasa k = new MojaKlasa(); k.metoda1(); k.metoda2(); k.metoda3();