Wykład 4: Klasy i Metody
Transkrypt
Wykład 4: Klasy i Metody
Wykład 4: Klasy i Metody Klasa Podstawa języka. Każde pojęcie które chcemy opisać w języku musi być zawarte w definicji klasy. Klasa definiuje nowy typ danych, których wartościami są obiekty: klasa to szablon dla obiektów ● obiekt to egzemplarz klasy ● Definicja Klasy class nazwa { //deklaracje pól typ pole1; ... typ poleN; //deklaracje metod typ metoda1(lista-parametrów) { //treść metody } ... typ metodaM(lista-parametrów) { //treść metody } } Przykład Klasy Klasa, która zawiera tylko trzy pola danych: class Pudelko { double szerokosc; double wysokosc; double glebokosc; } Utworzenie obiektu klasy, i przypisanie wartości polu tego obiektu: Pudelko mojePudelko = new Pudelko(); mojePudelko.szerokosc = 100; Wykorzystanie Klasy class PudelkoDemo { public static void main(String args[]) { Pudelko mojePudelko = new Pudelko(); double objetosc; mojePudelko.szerokosc = 10; mojePudelko.wysokosc = 20; mojePudelko.glebokosc = 15; } objetosc = mojePudelko.szerokosc * mojePudelko.wysokosc * mojePudelko.glebokosc; System.out.println(“Objetosc to “, objetosc); Kompilacja i Wykonanie Należy umieścić obie klasy w pliku PudelkoDemo.java: class Pudelko { ... } class PudelkoDemo { public static void main(...) { ... } } Kompilacja i wykonanie: > cd demonstracje/PudelkoDemo > javac PudelkoDemo.java > java PudelkoDemo Niezależność Pól Każdy obiekt ma własną kopie pól klasy: zmiana pola jednego nie ma wpływu na wartości pól drugiego. public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(); Pudelko mojePudelko2 = new Pudelko(); double objetosc; mojePudelko1.szerokosc = 10; ... mojePudelko2.szerokosc = 3; ... objetosc = mojePudelko1.szerokosc * ...; System.out.println(“Objetosc: “ + objetosc); objetosc = mojePudelko2.szerokosc * ...; System.out.println(“Objetosc: “ + objetosc); Deklaracja Obiektów Uzyskanie obiektów klasy, proces dwu-etapowy: ● Deklaracja zmiennej typu klasy: Box mybox; Powstaje zmienna odwołująca się do obiektu, której wartością jest na razie null. ● Uzyskanie adresu obiektu i przypisanie go zmiennej. mybox = new Box(); Operator new Alokuje pamięć dla obiektu i zwraca jego adres. zmiennaKlasy = new nazwaKlasy(); nazwaKlasy(): konstruktor klasy ● klasa może deklarować własny konstruktor, lub korzystać z domyślnego ● alokacja dynamiczna pamięci: tyle obiektów ile potrzeba, ale pamięci może brakować ● tworzenie zmiennych typów podstawowych nie wymaga new. ● Przypisania Zmiennych Obiektowych Przypisanie kopiuje adres, nie wartość: Box b1 = new Box(); Box b2 = b1; Obie zmienne wskazują na ten sam obiekt. Zmiennie nie są w żaden sposób połączone: ... b1 = null; b2 nadal wskazuje na oryginalny obiekt. Metody Klasy Ogólna postać definicji metody: type nazwa(lista-parametrow) { //treść metody return wartosc; //dalsza treść } ● type jest typem wartości zwracanych ● jeśli nie zwraca wartości, jej typem jest void ● ● ● nazwa jest nazwą metody lista-parametrow jest listą typów i nazw argumentów oddzielonych przecinkami return wartosc to wartość zwracana przez metodę Metody Klasy: Przykład Klasy definiują metody by ukrywać wewnętrzną strukturę danych, jak też na własny użytek. class Pudelko { double szerokosc, wysokosc, glebokosc; } //wyswietla objetosc pudelka void objetosc() { System.out.print(“Objetosc: “); System.out.println( szerokosc * wysokosc * glebokosc); } Odwołanie do pola w danej klasie można wykonać bezpośrednio. Metody Klasy: Przykład public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(); Pudelko mojePudelko2 = new Pudelko(); mojePudelko1.szerokosc = 10; ... mojePudelko2.szerokosc = 3; ... //wyswietl objetosc pierwszego pudelka mojePudelko1.objetosc(); } //wyswietl objetosc drugiego pudelka mojePudelko2.objetosc(); Odwołanie do pola w innej klasie niż bieżąca musi odbyć się przez obiekt tej klasy. Metoda Która Zwraca Wartość Typ wyrażenia które zwraca wartość metody musi być zgodny z typem wyniku tej metody: class Pudelko { double szerokosc, wysokosc, glebokosc; } //oblicza objetosc pudelka double objetosc() { return szerokosc * wysokosc * glebokosc; } Metoda Która Zwraca Wartość Typ zmiennej której przypisujemy wartość metody musi być zgodny z typem wyniku tej metody: public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(); Pudelko mojePudelko2 = new Pudelko(); double objetosc; mojePudelko1.szerokosc = 10; ... mojePudelko2.szerokosc = 3; ... objetosc = mojePudelko1.objetosc(); System.out.println(“Objetosc: “ + objetosc); } objetosc = mojePudelko2.objetosc(); System.out.println(“Objetosc: “ + objetosc); Metoda Która Posiada Parametry Parametry zwiększają stosowalność metod. ● Metoda bez parametrów: int kwadrat() { return 10 * 10; } ● Metoda z parametrem: int kwadrat(int i) { return i * i; } Parametr: zmienna która otrzymuje wartość gdy metoda jest wykonywana. Argument: wartość przekazywana metodzie. Metoda z Parametrami: Przykład class Pudelko { double szerokosc, wysokosc, glebokosc; //oblicza objetosc pudelka double objetosc() { return szerokosc * wysokosc * glebokosc; } } //ustala wymiary pudelka void ustalWymiary(double s, double w, double g) { szerokosc = s; wysokosc = w; glebokosc = g; } Metoda z Parametrami: Przykład public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(); Pudelko mojePudelko2 = new Pudelko(); double objetosc; mojePudelko1.ustalWymiary(10, 20, 15); mojePudelko2.ustalWymiary(3, 6, 9); objetosc = mojePudelko1.objetosc(); System.out.println(“Objetosc: “ + objetosc); } objetosc = mojePudelko2.objetosc(); System.out.println(“Objetosc: “ + objetosc); Konstruktory Konstruktor realizuje automatyczną inicjację obiektu zaraz po jego utworzeniu. Konstruktor posiada tą samą nazwę jak klasa w której się znajduje. Konstruktor piszemy bez typu wyniku: domyślnym typem konstruktora klasy jest ta sama klasa. Gdy klasa nie posiada konstruktora, domyślny konstruktor automatycznie inicjuje pola zerami. Konstruktor: Przykład class Pudelko { double szerokosc, wysokosc, glebokosc; //konstruktor pudelka Pudelko() { System.out.println(“Budujemy pudelko”); szerokosc = 10; wysokosc = 10; glebokosc = 10; } //oblicza objetosc pudelka double objetosc() { return szerokosc * wysokosc * glebokosc; } } Konstruktor: Przykład public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(); Pudelko mojePudelko2 = new Pudelko(); double objetosc; objetosc = mojePudelko1.objetosc(); System.out.println(“Objetosc: “ + objetosc); } objetosc = mojePudelko2.objetosc(); System.out.println(“Objetosc: “ + objetosc); Parametryzowany Konstruktor Wszystkie pudełka mają tą samą objętość. Potrzebujemy konstruktora, który tworzy pudełka różnych rozmiarów. class Pudelko { double szerokosc, wysokosc, glebokosc; //parametryzowany konstruktor pudelka Pudelko(double s, double w, double g) { szerokosc = s; wysokosc = w; glebokosc = g; } ... Parametryzowany Konstruktor public static void main(String args[]) { Pudelko mojePudelko1 = new Pudelko(10,20,15); Pudelko mojePudelko2 = new Pudelko(3,6,9); double objetosc; objetosc = mojePudelko1.objetosc(); System.out.println(“Objetosc: “ + objetosc); } objetosc = mojePudelko2.objetosc(); System.out.println(“Objetosc: “ + objetosc); Słowo Kluczowe this Odwołanie z metody do obiektu który ją wywołał. //zbedne uzycie “this” Pudelko(double s, double w, double g) { this.szerokosc = s; this.wysokosc = w; this.glebokosc = g; } Dozwolone wszędzie tam gdzie można odwołać się do obiektu bieżącej klasy. Przesłanianie Pól Nielegalne jest deklarowanie dwóch zmiennych o tej samej nazwie wewnątrz zawierających się bloków. Legalne jest deklarowanie zmiennych lokalnych i parametrów o tej samej nazwie jak pola klasy. Następuje przesłonięcie pól przez zmienne lokalne. Pudelko(double szerokosc, double wysokosc, double glebokosc) { this.szerokosc = szerokosc; this.wysokosc = wysokosc; this.glebokosc = glebokosc; } Metoda finalize() Dodatkowe czynności do wykonania gdy obiekt jest usuwany z pamięci, np. zwolnienie dostępu do pliku. Wykonywane przez metodę finalize(): protected void finalize() { ... } Metoda wywoływana jest przez odśmiecacz pamięci gdy ten usuwa niepotrzebny obiekt ze sterty. Przykład: Klasa Stos Stos przechowuje dane w porządku first-in last-out: pierwszy zapisany, ostatni odczytany. Oto implementacja 10-elementowego stosu: class Stos { int stos[] = new int[10]; int wskaznik; //inicjalizacja wskaznika Stos() { wskaznik = -1; } Przykład: Klasa Stos //zapis elementu na stosie void push(int element) { if (wskaznik == 9) System.out.println(“Stos jest pelny.”); else stos[++wskaznik] = element; } } //odczyt elementu ze stosu int pop() { if (wskaznik < 0) { System.out.println(“Stos jest pusty.”); return 0; } else return stos[wskaznik—]; } Przykład: Użycie Klasy Stos class TestStos { public static void main(String args[]) { Stos stos1 = new Stos(); Stos stos2 = new Stos(); for (int i=0; i<10; i++) stos1.push(i); for (int i=10; i<20; i++) stos2.push(i); System.out.println(“Pierwszy stos: “); for (int i=0; i<10; i++) System.out.println(stos1.pop()); } } System.out.println(“Drugi stos: “); for (int i=0; i<10; i++) System.out.println(stos2.pop());