Widoczności:
– public – widoczny dla wszystkich
– private – widoczny tylko wewnątrz danej klasy
– protected – widoczny w obrębie pakietu oraz w klasach potomnych z innych pakietów
– nienazwana (friendly) – jak public w obrębie pakietu
Modyfikatory:
– static - dostęp bez uprzedniego utworzenia
– final - brak możliwości zmiany (pola mogą być inicjalizowane w konstruktorze)
Zastosowanie widoczności:
– klasa – public / friendly
– klasa wewnętrzna – public / private / protected / friendly
– konstruktor – public / protected / friendly
– metoda – public / private / protected / friendly
– pole – public / private / protected / friendly
– stała – public / private
Dziedziczenie
.clone() - tworzy i zwraca kopię aktualnego obiektu
.equals(Object) - sprawdza, czy dany obiekt jest równy aktualnemu
.finalize() - metoda wywoływana przez Garbage Collector, gdy nie istnieje
żadna referencja do aktualnego obiektu
.getClass() - zwraca klasę reprezentującą obiekt
.hashCode() - zwraca wartość reprezentującą obiekt dla metody mieszającej
.toString() - zwraca reprezentację tekstową obiektu
this - wskazanie na aktualny obiekt
super – wskazanie na obiekt klasy bazowej (nadrzędnej)
instanceof – sprawdzenie, czy obiekt jest danej klasy
POLIMORFIZM
public class butelka {
int pojemnosc=500;
int zawartosc;
int nalej_recznie(int napoj)
{
return zawartosc=napoj;
}
int nalej_automatycznie()
{
return zawartosc=pojemnosc;
}
}
class Napoj_gazowany extends butelka
{
int pojemnosc=400;
int nalej_recznie(int napoj, int gaz)
{
return zawartosc=napoj-gaz;
}
int nalej_automatycznie()
{
return zawartosc=pojemnosc-(5*pojemnosc/100);
}
public static void main(String[] args)
{
butelka b = new butelka();
Napoj_gazowany ng = new Napoj_gazowany();
butelka b1 = new Napoj_gazowany();
System.out.println("Zawartosc butelki z napojem niegazowanym; "+b.nalej_automatycznie());
System.out.println("Zawartosc butelki z napojem gazowanym: "+ng.nalej_automatycznie());
System.out.println("Zawartosc butelki z napojem niegazowanym: "+b.nalej_recznie(500));
System.out.println("Zawartosc butelki z napojem gazowanym: "+ng.nalej_recznie(500, 10));
System.out.println(b1.nalej_recznie(500));
System.out.println(((Napoj_gazowany)b1).nalej_recznie(500, 20));
if(b1 instanceof Napoj_gazowany)
System.out.println("b1 instanceof Napoj_gazowany");
} }
Tablice:
– tworzenie tablicy jednowymiarowej typu int
int[] tab = new int[10];
– tworzenie tablicy wielowymiarowej
int[][] tab = new int[10][4];
– tworzenie i inicjalizacja zawartości tablicy
int[] tab = { 5, 3, 8, 2, 7 };
– liczba elementów tablicy
tab.length
– odwołanie do i-tego elementu tablicy
tab[i]
losowanie elementu:
public class Main {
public static void main(String[] args) {
// Stworzenie obiektu klasy Random, który posłuży do loswania liczb
Random r = new Random();
// Losowanie liczby z zakresu [0,10] do zmiennej a.
int a = r.nextInt(11); // deklaracja i definicja zmiennej
System.out.println(a);
// Losowanie liczby z zakresu [-5,15] i wyświetlenie jej na konsolę.
System.out.println( r.nextInt(21)-5 );
// 21, bo w przedziale [-5,15] jest 21 liczb i -5,
// bo to najmniejsza liczba w zakresie.
// Losowanie liczby z zakresu [-20,-10] do zmiennej a.
a = r.nextInt(11)-20;
System.out.println(a);
// 11, bo w przedziale [-20,10] jest 11 liczb i -20,
// bo to najmniejsza liczba w zakresie.
// Losowanie liczb z zakresu [x,y], gdzie x i y, to zmienne
// całkowitoliczbowe o dowolnej wartości.
int x = 7; // To wartość przykładowa
int y = 15; // To wartość przykładowa
a = r.nextInt(y-x+1)+x; // Od większej (y) odejmujemy mniejszą (x) i
// dodajemy 1 - to daje liczność zbioru
// (w losowaniu), a następnie dodajemy
// mniejszą (x), bo to najmniejsza liczba
// w zakresie.
System.out.println(a);
// Sprawdzenie powyższego przykładu dla liczb ujemnych:
x = -27; // To wartość przykładowa
y = -15; // To wartość przykładowa
a = r.nextInt(y-x+1)+x;
System.out.println(a);
// Sprawdzenie powyższego przykładu w sytuacji, kiedy jedna liczba
// jest ujemna, a druga dodatnia
x = -7; // To wartość przykładowa
y = 15; // To wartość przykładowa
a = r.nextInt(y-x+1)+x;
System.out.println(a);
}
Klasa
Klasy mogą zawierać zarówno metody jak i zmienne. Równie dobrze mogą mieć tylko jedne, lub drugie z tych elementów, a nawet nie posiadać ich wcale (choć po co komu taka klasa). Jak wyżej wspomnieliśmy każdą klasę rozpoczyna słowo kluczowe class, a te z kolei poprzedza specyfikator dostępu. Występuje wiele rodzajów klas i mają one różne przeznaczenie.
Obiekt
Jest to naturalna reprezentacja klasy. Przechowuje informacje o zmiennych i pozwala się do nich odwoływać, a także za jego pomocą możemy wywoływać metody. Przekonaliśmy się o tym już wielokrotnie, ponieważ użycie metody print() wyświetlającej tekst na ekranie to nic innego jak wywołanie tejże metody na rzecz obiektu out. Utworzenie nowego obiektu – czyli instancji klasy dokonujemy za pomocą słowa kluczowego new - podobnie jak miało to miejsce w przypadku tablic.
specyfikator_dostepu typ_Obiektu nazwaObiektu = new typ_Obiektu();
Metody
Oczywiście metoda main() nie musi być jedyną metodą danej klasy. Mogą być ich równie dobrze setki. Zbierając wszystkie informacje w całość możemy przedstawić przykład różnych metod w klasie:
public class Tablice{
public void metoda1(){
System.out.println("Ta metoda nic nie zwraca");
}
public int trzy(){
return 3; // ta metoda zwraca liczbę 3
}
public int suma(int a, int b){
return a+b; //ta metoda zwraca sumę dwóch parametrów
}
}
Klasa
Klasa to specyficzna konstrukcja języka skupiająca w sobie zmienne i funkcje (czyli atrybuty i metody) opisujące pewien fragment rzeczywistości. Zwykle pola zawierają informację o stanie tego wycinka rzeczywistości, a metody pozwalają na zmianę i kontrolę stanu.
Dla przykładu niech naszą klasą będą „samochody”.
Najprostszy zapis naszej klasy będzie wyglądał następująco:
public class samochod{
}
Pada tu słówko public. Poniżej zamieszczam wyjaśnienie jego zastosowania wraz z innymi opcjami jakie możemy wykorzystać przy deklarowaniu klasy:
public - klasa może być dziedziczona przez inne klasy.
abstract - klasa jest klasą abstrakcyjną
final - klasa nie może być dziedziczona
extends Super - nazwa klasy, którą dziedziczy dana klasa
implements Interfaces - interfejs/y, który/e implementuje dana klasa
Obiekt
Obiekt jest to wystąpienie (instancja) klasy — o ile klasa zawiera opis pewnego fragmentu rzeczywistości, o tyle obiekt konkretyzuje klasę. W językach programowania o ścisłej kontroli typów można powiedzieć, że klasa jest typem złożonym, natomiast obiekt jest zmienną tego typu.
Naszym obiektem może być np. „opel”, czyli już właściwy przedstawiciel (instancja) klasy „samochod”.
Metoda
jest to funkcja składowa klasy, której zadaniem jest działanie na rzecz określonych elementów danej klasy lub klas z nią spokrewnionych.
Niech naszą metoda nazywa się jedz().
Zaimplementowana w naszej klasie może mieć następującą postać:
public class samochod{
public void jedz(int ile){
przebieg +=ile;
}
}
O tym, w jaki sposób wywołać tą metodę (sprawdzić ją w działaniu) napiszę za chwilę. Brakuje nam też deklaracji zmiennej przebieg (będącej atrybutem klasy).
Atrybut
Zmienna wewnątrz klasy oznaczająca stan obiektu.
Kontynuując nasz motoryzacyjny przykład dopiszmy atrybut przebieg.
public class samochod{
private int przebieg;
public void jedz(int ile){
przebieg +=ile;
}
}
Metody i atrybuty nazywamy składowymi klasy. Każda składowa klasy może być:
private - prywatna, dostępna tylko w danej klasie
protected - chroniona lub zabezpieczona, dostępna z danej klasy i wszystkich klas ją dziedziczących
public - publiczna, dostępna zewsząd
Konstruktor
Jest to specjalna metoda danej klasy, wywoływana podczas tworzenia jej instancji. Zadaniem konstruktora jest zainicjowanie obiektu, a w niektórych językach programowania także utworzenie obiektu.
Zadania konstruktora:
Wywołanie konstruktora powoduje wykonanie następujących zadań:
obliczenie rozmiaru obiektu
alokacja obiektu w pamięci
wyczyszczenie (zerowanie) obszaru pamięci zarezerwowanej dla obiektu (tylko w niektórych językach)
wpisanie do obiektu informacji łączącej go z odpowiadającą mu klasą (połączenie z metodami klasy)
wykonanie kodu klasy bazowej (w niektórych językach niewymagane)
wykonanie kodu wywołanego konstruktora
Z wyjątkiem ostatniego punktu powyższe zadania są wykonywane wewnętrznie i są wszyte w kompilator lub interpreter języka, a w niektórych językach stanowią kod klasy bazowej.
W językach programowania w różny sposób oznacza się konstruktor. W C++ oraz Javie - jest to metoda o nazwie zgodnej z nazwą klasy.
Stwórzmy więc konstruktor dla naszej klasy samochód:
public class samochod{
private int przebieg;
private String model;
private int predkoscmax;
public samochod(int przebieg ){
this.przebieg = przebieg;
}
public void jedz(int ile){
przebieg +=ile;
}
public int aktualnyprzebieg(){
return this.przebieg;
}
}
Jego wykorzystanie znajdzie się wewnątrz metody main i będzie wyglądało następująco:
public static void main( String [] args ){
samochod opel = new samochod(45000); // budujemy nowe autko z przebiegiem 45tyś.km. :) vel tworzymy obiekt
opel.jedz(120); // jedziemy 120 km
System.out.print(opel.aktualnyprzebieg()); // sprawdzamy aktualny przebieg
}
Abstrakcja
Każdy obiekt w systemie służy jako model abstrakcyjnego "wykonawcy", który może wykonywać pracę, opisywać i zmieniać swój stan oraz komunikować się z innymi obiektami w systemie, bez ujawniania, w jaki sposób zaimplementowano dane cechy. Procesy, funkcje lub metody mogą być również abstrahowane, a kiedy tak się dzieje, konieczne są rozmaite techniki rozszerzania abstrakcji.
Hermetyzacja
Czyli ukrywanie implementacji, enkapsulacja. Zapewnia, że obiekt nie może zmieniać stanu wewnętrznego innych obiektów w nieoczekiwany sposób. Tylko wewnętrzne metody obiektu są uprawnione do zmiany jego stanu. Każdy typ obiektu prezentuje innym obiektom swój interfejs, który określa dopuszczalne metody współpracy. Pewne języki osłabiają to założenie, dopuszczając pewien poziom bezpośredniego (kontrolowanego) dostępu do "wnętrzności" obiektu. Ograniczają w ten sposób poziom abstrakcji. Przykładowo, w niektórych kompilatorach języka C++ istnieje możliwość tymczasowego wyłączenia mechanizmu enkapsulacji; otwiera to dostęp do wszystkich pól i metod prywatnych, ułatwiając programistom pracę nad pośrednimi etapami tworzenia kodu i znajdowaniem błędów.
Polimorfizm
Referencje i kolekcje obiektów mogą dotyczyć obiektów różnego typu, a wywołanie metody dla referencji spowoduje zachowanie odpowiednie dla pełnego typu obiektu wywoływanego. Jeśli dzieje się to w czasie działania programu, to nazywa się to późnym wiązaniem lub wiązaniem dynamicznym. Niektóre języki udostępniają bardziej statyczne (w trakcie kompilacji) rozwiązania polimorfizmu - na przykład szablony i przeciążanie operatorów w C++.
Dziedziczenie
Porządkuje i wspomaga polimorfizm i enkapsulację dzięki umożliwieniu definiowania i tworzenia specjalizowanych obiektów na podstawie bardziej ogólnych. Dla obiektów specjalizowanych nie trzeba redefiniować całej funkcjonalności, lecz tylko tę, której nie ma obiekt ogólniejszy. W typowym przypadku powstają grupy obiektów zwane klasami, oraz grupy klas zwane drzewami. Odzwierciedlają one wspólne cechy obiektów.