Dziedziczenie. Enkapsulacja. Składowe statyczne. Korzystanie z

Transkrypt

Dziedziczenie. Enkapsulacja. Składowe statyczne. Korzystanie z
Programowanie w Javie
Wykład 3:
•
•
•
•
•
Dziedziczenie
Enkapsulacja
Składowe statyczne
Korzystanie z dokumentacji
Typ wyliczeniowy
Kluczowe pojęcia programowania obiektowego
• dziedziczenie (inheritance)
• enkapsulacja (encapsulation - kapsułkowanie,
hermetyzacja)
• polimorfizm (polimorphism - wielopostaciowość),
następny wykład
Dziedziczenie
Klasa potomna, klasa bazowa
class Osoba {
String imie;
int wiek;
void info(){
System.out.println("Imię: " + imie + ", Wiek: " + wiek);
}
}
class Student extends Osoba {
int grupa;
}
•
•
•
•
•
Osoba - klasa bazowa (nadrzędna, nadklasa - superclass) klasy Student
Student - klasa potomna (podrzędna, podklasa - subclass) klasy Osoba.
Mówimy: Student jest klasą potomną klasy Osoba (albo rozszerza klasę Osoba)
Klasę potomną definiujemy używając słowa kluczowego extends.
Klasa potomna dziedziczy składowe klasy bazowej oraz może mieć dodatkowe własne składowe. W naszym przypadku klasa Student posiada pola: imie, wiek
(dziedziczone) i grupa (własne) oraz metodę info (dziedziczoną)
Przykład: Program.java (Odkomentuj "Klasa potomna")
Przesłanianie (nadpisywanie, overriding) metod
Przesłonięcie metody - zdefiniowanie w klasie potomnej metody o tej samej nazwie i
liście parametrów co w klasie bazowej
class Osoba {
String imie;
int wiek;
void info(){
System.out.println("Imię: " + imie + ", Wiek: " + wiek);
}
}
class Student extends Osoba {
int grupa;
void info(){
System.out.println("Imię: " + imie + ", Wiek: " + wiek + ", Grupa: " + grupa);
}
}
Metoda info() klasy Student przesłania metodę info() klasy Osoba.
Wywołanie metody info() dla obiektu klasy Student wypisze imię, wiek i grupę.
Przykład: Program.java (Odkomentuj "Overriding")
Słowo kluczowe super - wywołanie metody klasy bazowej
Zamiast
class Student extends Osoba {
int grupa;
void info(){
System.out.println("Imię: " + imie + ", Wiek: " + wiek + ", Grupa: " + grupa);
}
}
Można tak:
class Student extends Osoba {
int grupa;
void info(){
super.info(); // wywołanie metody info() klasy bazowej czyli klasy Osoba
System.out.println("Grupa: " + grupa);
}
}
Instrukcją super.nazwaMetody(argumenty) wywołujemy metodę klasy bazowej.
Jak widzimy możliwe jest zatem wywołanie metody przesłoniętej.
Przykład: Program.java (Odkomentuj "Super")
Konstruktory (cz. 1)
•
Przypomnienie1: gdy tworzymy obiekt jest wywoływana specjalna metoda
zwana konstruktorem.
•
Gdy tworzymy obiekt klasy potomnej to zanim zostanie wywołany jego
konstruktor jest wywoływany konstruktor klasy bazowej.
•
Dlaczego jest wywoływany konstruktor klasy bazowej?
Obiekt klasy potomnej może mieć pola własne, ale ponadto dziedziczy pola
klasy bazowej. Zatem, aby miał co dziedziczyć (czyli posiadał te pola
dziedziczone), musi istnieć obiekt klasy bazowej. Stąd potrzeba powstania
obiektu klasy bazowej.
•
Przypomnienie2: Jeśli nie zdefiniujemy konstruktora jest automatycznie
tworzony konstruktor domyślny i on jest wywoływany.
•
Czyli jeśli nie zdefiniujemy konstruktorów w klasie bazowej i potomnej to
będą tam automatycznie utworzone konstruktory domyślne i to one będą
wywołane przy tworzeniu obiektu klasy potomnej
Konstruktory (cz. 2)
Przypomnienie3: konstruktor domyślny przypisuje wartości domyślne polom
obiektu
Zatem obiektowi klasy potomnej zostaną przypisane wartości domyślne
zarówno dla jego pól własnych jak i dla pól dziedziczonych
Przykłady:
Program.java (Odkomentuj "Konstruktory domyślne")
Program.java (Odkomentuj "Konstruktory ")
Konstruktory (cz. 3)
Co jeśli w klasie bazowej są tylko konstruktory z parametrami
W takiej sytuacji, tworząc obiekt klasy potomnej musimy sami wywołać
konstruktor klasy bazowej. Jeśli tego nie zrobimy kompilator zgłosi błąd.
Przykład: Program.java (Odkomentuj "Gdy w klasie bazowej ...")
Jak wywołać konstruktor klasy bazowej? Następny slajd.
Metoda super() - wywołanie konstruktora klasy bazowej
•
Metoda super() wywołuje konstruktor klasy bazowej.
•
Który konstruktor wywoła super() jeśli w klasie bazowej jest wiele
konstruktorów?
Ten, którego parametry zgadzają się z argumentami jakie podaliśmy dla
super
Przykład: Program.java (Odkomentuj "Metoda super")
Uwaga: super() musi być pierwszą instrukcją w konstruktorze klasy potomnej.
Analogia z this().
this() wywołuje konstruktor klasy bieżącej, zaś super() konstruktor klasy
bazowej
Enkapsulacja
Definicja
Wróćmy do zagadnienia dostępu do pól klasy.
Definiowaliśmy metody "settery" i "gettery", aby za pomocą nich
ustawiać i odczytywać wartości pól. Nie chcemy, aby można to
było zrobić bezpośrednio odwołując sie do pola, bo może to np.
spowodować ustawienie niepoprawnych danych (np. wiek = -3).
Mechanizm enkapsulacji pozwala ograniczyć dostęp do klas i
składowych.
Enkapsulacja (kapsułkowanie) - ograniczenie dostępu do klas i ich
składowych (nie tylko pól) z poziomu innej klasy.
Innymi słowy: klasa lub składowe mogą być zamknięte
(zakapsułkowane) przed dostępem z poziomu innej klasy.
Ograniczenie dostępu oznacza:
•
w przypadku pól: ograniczenie możliwości zmiany wartości pola i odczytania
wartości pola z poziomu innej klasy
•
w przypadku metod: ograniczenie możliwości wywołania metod z poziomu
innej klasy
•
w przypadku klas: ograniczenie możliwości dostępu do klasy z poziomu innej
klasy.
Dostęp zadeklarowany dla klasy przenosi się na jej składowe chyba, że
składowe mają zadeklarowany dostęp
bardziej ograniczony.
Np. klasa publiczna, a jej metoda prywatna, więc dostęp do tej metody
będzie prywatny a nie publiczny.
Ale np. klasa pakietowa, a jej metoda publiczna, to dostęp do tej metody
będzie jednak pakietowy a nie publiczny.
Specyfikatory dostępu do składowych
Dostęp do składowych ustawiamy dopisując przy składowej następujące
specyfikatory (modyfikatory) dostępu.
Są cztery możliwości (4 poziomy dostępu):
– public (dostęp do składowej nieograniczony-publiczny to
znaczy z każdej innej klasy)
– private (dostęp do składowej prywatny to znaczy tylko z
wnętrza danej klasy)
– protected (dostęp do składowej chroniony to znaczy tylko z
wnętrza danej klasy lub z klasy potomnej lub z klasy, która jest w
tym samym pakiecie)
– gdy nie ma specyfikatora to dostęp do składowej jest pakietowy
to znaczy tylko z klas, które należą do tego samego pakietu
Specyfikator wpisuje się przed typem pola lub przed typem zwracanego przez
metodę wyniku. Na razie tylko zapoznamy się z dostępem prywatnym do pól.
Przykład: Program.java (Odkomentuj "Przykład dostęp prywatny")
Specyfikatory dostępu do klas
W przypadku klas mamy dwa 2 poziomy dostępu i ustawiamy je za
pomocą następujących specyfikatorów:
– public (dostęp do klasy jest nieograniczony-publiczny to znaczy
z każdej innej klasy)
– gdy nie ma wpisanego specyfikatora to dostęp do klasy jest
pakietowy to znaczy dostęp do takiej klasy mają tylko klasy z tego
samego pakietu.
Specyfikator wpisuje się przed nazwą klasy.
public class nazwaKlasy {
...
}
Składowe statyczne. Słowo kluczowe static. (1)
Są to składowe, do których możemy się odwołać bez konieczności
tworzenia obiektu danej klasy.
Składowe statyczne definiujemy dodając słowo kluczowe static:
• w przypadku pola przed typem pola
• w przypadku metody przed typem wyniku, który ta metoda
zwraca
Do składowych statycznych odwołujemy się:
• nazwaKlasy.nazwaPolaStatycznego
• nazwaKlasy.nazwaMetodyStatycznej()
gdzie nazwaKlasy to nazwa klasy, w której jest zdefiniowana składowa
statyczna do której się odwołujemy
Składowe statyczne. Słowo kluczowe static. (2)
Uwaga:
Jeśli klasa ma pole statyczne to jest ono wspólne dla wszystkich
obiektów tej klasy. Inaczej mówiąc wartość pola statycznego jest
taka sama we wszystkich obiektach tej klasy.
Czyli jeśli zmienimy wartość pola statycznego to zmieni się ono we
wszystkich obiektach tej klasy.
Przykład:
Program.java (Odkomentuj "Przykład Składowe statyczne")
Korzystanie z dokumentacji na przykładzie klasy Math (1)
Oprócz definiowania własnych klas możemy też korzystać z klas już
zdefiniowanych (gotowych) - z biblioteki klas. Wchodzą one w
skład platformy Java.
Obejrzyjmy jedną z takich klas bibliotecznych: klasę Math
Klasy biblioteczne można obejrzeć korzystając z dokumentacji.
Dostęp do dokumentacji:
• online: http://docs.oracle.com/javase/8/docs/api/
• lokalnie: folder_jdk/docs/index.html (po otwarciu strony kliknąć
w link "Java SE API")
Korzystanie z dokumentacji na przykładzie klasy Math (2)
Klasa Math znajduje się w pakiecie java.lang. Po wejściu do
dokumentacji dostajemy listę pakietów i klikamy w link "java.lang".
Wyświetli nam się lista klas tego pakietu, wśród których jest klasa
Math. Obok jest opis: klasa zawiera metody do wykonania działań
matematycznych (numerycznych): podniesienie do potęgi,
obliczenie logarytmu, pierwiastka itd.
Klikamy w link "Math" i wyświetli się lista pól i metod tej klasy.
M.in. mamy: pole statyczne PI typu double i metodę statyczną
random() , która zwraca liczbę losową z zakresu [0,1).
Użyjmy tych składowych:
Przykład: Program.java (Odkomentuj "Przykład Math")
Typ wyliczeniowy (Enumeration)
Typ wyliczeniowy to lista stałych.
Definicja typu wyliczeniowego:
enum Rozmiar {
mały, średni, duży;
}
Typ wyliczeniowy jest klasą. Różnica z definicją zwykłej klasy:
używamy słowa kluczowego enum zamiast class. Pola tej klasy w
naszym przykładzie to mały, średni i duży. Pola te są stałymi.
Deklaracja i inicjalizacja zmiennej typu wyliczeniowego:
Rozmiar rozmiar = Rozmiar.mały;
Wypisanie wartości zmiennej:
System.out.println(rozmiar); // wypisze napis "mały"
Przykład: Program.java (Odkomentuj "Typ wyliczeniowy")

Podobne dokumenty