Wykład 7: Pakiety i Interfejsy

Transkrypt

Wykład 7: Pakiety i Interfejsy
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
pakiet1\pakiet11\pakiet111
pakiet1:pakiet11:pakiet111
system Unix
system Windows
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
pod-klasa
nie
tak
tak
tak
jeden pakiet
nie pod-klasa
nie
tak
tak
tak
różne pakiety
pod-klasa
nie
nie
tak
tak
różne pakiety
nie pod-klasa
nie
nie
nie
tak
Ochrona Dostępu: Przykład
Nad-klasa w pakiecie p1:
package p1;
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
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
typ
...
typ
typ
...
typ
}
interface nazwa {
metoda1(lista-parametrów);
metodaN(lista-parametrów);
zmienna1 = wartość;
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();

Podobne dokumenty