Wykład 5: Więcej o Klasach i Metodach

Transkrypt

Wykład 5: Więcej o Klasach i Metodach
Wykład 5:
Więcej o Klasach i Metodach
Przeciążanie Metod
Klasa posiada dwie lub więcej metod o tej samej
nazwie ale różnych deklaracjach parametrów.
Java używa liczby i typów argumentów by ustalić
którą wersję metody należy wywołać.
Przeciążanie metod plus dziedziczenie to sposób na
implementację polimorfizmu.
Demo: Przeciążanie Metod
class Metody {
void test() {
System.out.println("Brak parametrow");
}
void test(int a) {
System.out.println("a: " + a);
}
void test(int a, int b) {
System.out.println("a i b: " + a + " " + b);
}
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
}
Demo: Przeciążanie Metod
class PrzeciazanieMetod {
public static void main(String args[]) {
Metody m = new Metody();
double wynik;
m.test();
m.test(10);
m.test(10, 20);
wynik = m.test(12.5);
System.out.println("test(12.5): " + wynik);
}
}
Różne Typy Wyników
Różne typy wynikowe nie wystarczają:
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
int test(double a) {
System.out.println("double a: " + a);
return (int)(a*a);
}
Przeciążanie i Konwersja Typów
Automatyczna kowersja typów gdy nie istnieje metoda
o dokładnym typie wywołania:
void test() {
System.out.println("Brak parametrow”);
}
void test(double a) {
System.out.println("double a: " + a);
}
int i = 88;
test();
test(i);
Przeciążanie i Polimorfizm
W językach bez przeciążania, każda metoda musi
posiadać unikalna nazwę:
int abs(int i)
long labs(long i)
float fabs(float i)
Java umożliwia wystąpienie powiązanych metod pod
jedną nazwą: jeden interfejs, wiele metod.
static int abs(int i)
static long abs(long i)
static float abs(float i)
Przeciążanie Konstruktorów
Różne metody tworzena obiektów klasy przez
przeciążanie konstruktorów.
class Pudelko {
double szerokosc;
double wysokosc;
double glebokosc;
Obliczanie i wyświetlanie objętości:
void objetosc() {
System.out.println(
szerokosc * wysokosc * glebokosc);
}
Przeciążanie Konstruktorów
Konstruktory z trzema parametrami, z jednym
parametrem, i bez parametrów.
Pudelko(double s, double w, double g) {
szerokosc = s; wysokosc = w; glebokosc = g
}
Pudelko(double b) {
szerokosc = wysokosc = glebokosc = b;
}
Pudelko() {
szerokosc = wysokosc = glebokosc = -1;
}
}
Demo: Przeciążanie Konstruktorów
class PrzeciazanieKonstruktorow {
public static void main(String args[]) {
Pudelko p1 = new Pudelko(10,20,15);
Pudelko p2 = new Pudelko(10);
Pudelko p3 = new Pudelko();
p1.objetosc();
p2.objetosc();
p3.objetosc();
}
}
Obiekty jako Parametry
Metoda może posiadać parametry typów prostych.
Można też przekazywać do metody obiekty.
class Test {
int a, b;
Test(int i, int j) {
a = i; b = j;
}
Czy obiekt bieżący jest równy parametrowi metody?
boolean equals(Test o) {
if (o.a == a && o.b == b) return true;
else return false;
}
Demo: Przekazywanie Obiektów
class PrzekazywanieObiektowMetodom {
public static void main(String args[]) {
Test o1 = new Test(10,20);
Test o2 = new Test(10,20);
Test o3 = new Test(1,1);
System.out.println(“o1==o2:” +o1.equals(o2));
System.out.println(“o1==o3:” +o1.equals(o3));
}
}
Inicjacja Obiektu Obiektem
Często przekazujemy obiekty konstruktorom: jeden
obiekt inicjalizuje drugi.
class Pudelko {
double szerokosc;
double wysokosc;
double glebokosc;
}
Pudelko(Pudelko p) {
szerokosc = p.szerokosc;
wysokosc = p.wysokosc;
glebokosc = p.glebokosc;
}
...
Demo: Inicjacja Obiektu Obiektem
class PrzekazywanieObiektowKonstruktorom {
public static void main(String args[]) {
Pudelko p1 = new Pudelko(10,20,30);
Pudelko p2 = new Pudelko(p1);
}
}
p1.objetosc();
p2.objetosc();
Przekazywanie Argumentów
Dwie metody przekazywania argumentów metodom:
●
●
przez wartość: przekazanie kopii wartości
argumentu - zmiany parametru formalnego nie
mają wpływu na wartość argumentu wywołania
przez nazwę: przekazanie odwołania do argumentu
– zmiana parametru formalnego powoduje zmianę
wartości argumentu wywołania
Java używa obu metod.
Przekazywanie Typów Prostych
Przekazywanie argumentów typów prostych odbywa
się przez wartość.
class Test {
void metoda(int i, int j) {
i *= 2;
j /= 2;
}
}
Demo: Przekazywanie Typów Prostych
class WywolaniePrzezWartosc {
public static void main(String args[]) {
Test o = new Test();
int a = 10;
int b = 20;
System.out.println(
“przed wywolaniem: “ + a + “ “ + b);
}
}
o.metoda(a, b);
System.out.println(
“po wywolaniu: “ + a + “ “ + b);
Przekazywanie Obiektów
Obiekty przekazywane są przez nazwę: parametr
uzyskuje ten sam adres obiektu jak argument.
class Test {
int a, b;
Test(int i, int j) {
a = i; b = j;
}
void metoda(Test o) {
o.a *= 2; o.b /= 2;
}
}
Demo: Przekazywanie Obiektów
class WywolaniePrzezNazwe {
public static void main(String args[]) {
Test o = new Test(10, 20);
System.out.println(
“przed wywolaniem: “ + o.a + “ “ + o.b);
}
}
o.metoda(o);
System.out.println(
“po wywolaniu: “ + o.a + “ “ + o.b);
Zwracanie Obiektów
Metody mogą zwracać wartości typów prostych, jak
też obiekty dowolnych klas.
class Test {
int a;
Test(int i) {
a = i;
}
Test doKwadratu() {
Test temp = new Test(a * a);
return temp;
}
}
Demo: Zwracanie Obiektów
class ZwracanieObiektow {
public static void main(String args[]) {
Test o1 = new Test(2);
Test o2;
o2 = o1.doKwadratu();
System.out.println(“o1.a: “ + o1.a);
System.out.println(“o2.a: “ + o2.a);
}
}
o2 = o2.doKwadratu();
System.out.println(“drugie wywolanie“);
System.out.println(“o2.a: “ + o2.a);
Rekursja
Metoda rekurencyjna to metoda która wywołuje
samą siebie (dla innych wartości argumentów):
następuje alokacja pamięci na stosie dla
zmiennych lokalnych i parametrów
●
kod metody jest wywołany ponownie dla nowych
wartości argumentów
●
powrót powoduje usunięcie ze stosu parametrów i
zmiennych, i kontynuację za punktem wywołania
●
Demo: Rekursja
class Silnia {
int silnia(int n) {
if (n == 1) return 1;
return n * silnia(n-1);
}
}
class Rekursja {
public static void main(String
Silnia s = new Silnia();
System.out.println(“dla 3: “
System.out.println(“dla 5: “
System.out.println(“dla 8: “
}
}
args[]) {
+ s.silnia(3));
+ s.silnia(5));
+ s.silnia(8));
Demo: Rekursja i Tablice
class Tablica {
int wartosci[];
Tablica(int i) {
wartosci = new int[i];
}
}
void wyswietlTablice(int i) {
if (i == 0) return;
else wyswietlTablice(i-1);
System.out.print(“[“ + (i-1) + “] “);
System.out.println(wartosci[i-1]);
}
Demo: Rekursja i Tablice
class RekursjaDlaTablic {
public static void main(String args[]) {
Tablica t = new Tablica(10);
int i;
for (i=0; i<10; i++) t.wartosci[i] = i;
}
}
t.wyswietlTablice(10);
Kontrola Dostępu
Enkapsulacja umożliwia: połączenie danych i kodu, oraz
kontrolę dostępu do wnętrza klasy.
●
●
Zapobiega użyciu klasy w sposób niepożądany, np.
aby dane były dostępne przez dostarczone metody.
Umożliwia wymianę implementacji przy zachowaniu
interfejsu klasy.
Kontrola Dostępu
Cztery specyfikatory dostępu do elementów klasy:
public – dostępny dla każdej części programu
●
private – tylko dla składowych danej klasy
●
default – public dla składowych pakietu gdzie
znajduje się element, private dla reszty
●
protected – opisany później
●
Specyfikator poprzedza resztę definicji elementu:
private int i;
public static void main(...)
Demo: Kontrola Dostępu
class Test {
int a;
public int b;
private int c;
void zmienC(int i) {
c = i;
}
}
int zwrocC() {
return c;
}
Demo: Kontrola Dostępu
class KontrolaDostepu {
public static void main(String args[]) {
Test t = new Test();
t.a = 10;
t.b = 20;
// t.c = 30 !BLAD!
t.zmienC(30);
}
}
System.out.print(“a, b i c: “ + t.a + “ “);
System.out.println(t.b + “ “ + t.zwrocC());
Demo: Stos i Kontrola Dostępu
class Stos {
private int stos[] = new int[10];
private int wskaznik;
Stos() { ... }
void push(int element) { ... }
int pop() { ... }
}
Statyczne Składowe Klasy
Normalnie, elementy klasy (pola i metody) mogą być
tylko użyte poprzez obiekty tej klasy.
Elementy statyczne są niezależne od obiektów klasy:
●
statyczne dane
static int dane;
●
statyczna metoda
static void metoda();
●
statyczny blok – inicjacja elementów statycznych
static { ... }
Statyczne Składowe Klasy
Sposób wywołania:
nazwaklasy.metoda()
nazwaklasy.zmienna
Ograniczenia:
tylko odwołania do metod i danych statycznych
●
nie mogą zawierać odwołań do this czy super
●
Demo: Statyczne Składowe Klasy
class SkladoweStatyczne {
static int a = 3;
static int b;
static void metoda(int x) {
System.out.println(“x = + x);
System.out.println(“a = + a);
System.out.println(“b = + b);
}
//wykonywany raz gdy klasa jest ladowana
static {
System.out.println(“Inicjalizacja”);
b = a * 4
}
public static void main(String args[]) {
metoda(42);
}
}
Demo: Wywołanie Statyczne
class Statyczne {
static int a = 3;
static int b = 99;
static void wywolajMnie() {
System.out.println(“a = “ + a);
}
}
class WywolanieStatyczne {
public static void main(String args[]) {
Statyczne.wywolajMnie();
System.out.print(“b = “);
System.out.println(Statyczne.b);
}
}
Zmienne Final
Deklaracja zmiennej jako final zapobiega zmianie jej
wartości po zainicjowaniu.
final int FILE_NEW = 1;
final int FILE_OPEN = 2;
final int FILE_CLOSE = 3;
Zmienna jest faktycznie stałą.
Metody są też deklarowane jako final ale znaczenie
tego jest zupełnie odmienne.
Tablice jako Obiekty
Tablica jest zaimplementowana jako obiekt.
Jednym z atrybutów tego obiektu jest length:
ilość elementów które tablica może zawierać.
class DlugoscTablicy {
public static void main(String args[]) {
int a1[] = new int[10];
int a2[] = {3, 5, 7, 9, 11, 13, 15, 17};
System.out.println(“a1: “ + a1.length);
System.out.println(“a2: “ + a2.length);
}
}
Demo: Stos Dowolnej Długości
class Stos {
private int stos[];
private int wskaznik;
Stos(int rozmiar) {
stos = new int[rozmiar];
wskaznik = -1;
}
void push(int element) {
if (wskaznik == stos.length-1)
System.out.println("Stos jest pelny.");
else
stos[++wskaznik] = element;
}
}
int pop() { ... }
Klasa Zagnieżdżona
Klasa zagnieżdżona: definiowana wewnątrz innej klasy.
Ma dostęp do wszystkich elementów, również
prywatnych, klasy zewnętrznej.
●
Nie jest widoczna na zewnątrz klasy zewnętrznej.
●
Klasa zewnętrzna ma dostęp do klasy zagnieżdżonej,
ale nie jej elementów.
●
Statyczna klasa zagnieżdżona: musi odwoływać się do
elementów klasy zewnętrznej przez obiekty tej klasy.
Klasa Wewnętrzna
Nie-statyczna klasa zagnieżdżona: ma bezpośredni
dostęp do zmiennych i metod klasy zewnętrznej.
class Zewnetrzna {
int x = 100;
class Wewnetrzna {
int y = 200;
void wyswietl() {
System.out.println(“x = “ + x);
}
}
Klasa Wewnętrzna
void test() {
Wewnetrzna w = new Wewnetrzna();
w.wyswietl();
//System.out.println(y); //!BLAD!
}
}
class KlasaWewnetrzna {
public static void main(String args[]) {
//Wewnetrzna w = new Wewnetrzna(); //!BLAD!
Zewnetrzna z = new Zewnetrzna();
z.test();
}
}

Podobne dokumenty